summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus
diff options
context:
space:
mode:
authorlundinc <lundinc@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2020-03-24 21:54:22 +0000
committerlundinc <lundinc@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>2020-03-24 21:54:22 +0000
commitf5221dff43de249079c2da081723cb7a456f981f (patch)
tree54c1428d3909aa7e3b2cf7bd2c8b67975886a60a /FreeRTOS-Plus
parentbcf16bcbc0e3cb060d0c4fc2fc3bda5a38f3d745 (diff)
downloadfreertos-f5221dff43de249079c2da081723cb7a456f981f.tar.gz
commit 9f316c246baafa15c542a5aea81a94f26e3d6507
Author: David Vrabel <david.vrabel@cambridgeconsultants.com> Date: Mon Mar 16 11:21:46 2020 +0000 Demo/Posix_GCC: add demo application for Posix port using GCC This is largely a copy of the Windows demo application with a few key changes: - heap_3 (use malloc()/free()) so tools like valgrind "just work". - printf() wrapped in a mutex to prevent deadlocks on the internal pthread mutexes inside printf(). SCons (https://scons.org/) is used as the build system. This will be built as a 64-bit application, but note that the memory allocation trace points only record the lower 32-bits of the address. commit f78f919b3e2f0d707531a301a8ca07cd02bc4778 Author: Markus Rinne <markus.ka.rinne@gmail.com> Date: Thu Mar 19 21:00:24 2020 +0200 Fix function comments commit 1cd2d38d960a3576addb224582c88489bade5141 Author: David Chalco <david@chalco.io> Date: Fri Mar 20 10:29:05 2020 -0700 unix separators for path and remove .exe suffix from risc compiler (works on windows/mac) commit 938b19419eded12817737ab0644e94ed2ba7e95d Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Thu Mar 19 18:23:09 2020 -0700 Removing ./FreeRTOS-Labs directory, since: - IoT libraries are now in LTS branch. - FAT/POSIX/Light-weight MQTT are in https://github.com/FreeRTOS/FreeRTOS-Labs. commit 1a4abbc9e91b13fd6394464ade59d5e048320c7c Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Tue Mar 17 19:30:02 2020 -0700 Maintenance -- clean up readme.txt and add url to GitHub. (#38) * Removing readme.txt, as now we have README.md in place. The only information missing from README.md is about FAQ. * Adding FAQ information in README.md. * Adding a .url to root to redict user to FreeRTOS github home page. commit 47bb466aa19395b7785bcb830e2e4dd35f6bafc5 Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Tue Mar 17 13:07:44 2020 -0700 Update issue templates Template maintenance. - adding title prefix. - adding examples to "additional context" section. commit f506290041f56867765f8efa70ed2862125bdb7c Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Tue Mar 17 10:15:07 2020 -0700 Create SECURITY.md Apply the recommended SECURITY.md from AWS to our repo. commit 8982a2f80a80a2a0a47cf82de07b52101bd9d606 Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Fri Mar 13 12:50:10 2020 -0700 Add ./lib directory to make sure Zynq project compiles. commit ecf0f12aa14ad6fdafe1ef37257cbb4e03e2abd5 Author: AniruddhaKanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Wed Mar 11 10:19:48 2020 -0700 Sync up with Amazon-freertos repo (10th March 2020) (#34) * Sync up with amazon-freertos * Sync up with amazon-freertos * Sync up with amazon-freertos commit 0acffef047973e2e61c2201fd69cd9bbd317f674 Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Tue Mar 10 10:20:48 2020 -0700 GitHub PR template. (#29) commit c40a6da2e4cb8042b56d1b174051cbbe9813781a Author: AniruddhaKanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Mon Mar 9 11:18:48 2020 -0700 pass payload length when calling UDP callback (#30) * pass payload length when calling UDP callback commit 12d580e93d4d9074b9a867632f0681a511b4ad12 Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Fri Mar 6 18:16:51 2020 -0800 Update issue templates Initial issue template. Created following https://help.github.com/en/github/building-a-strong-community/configuring-issue-templates-for-your-repository#configuring-the-template-chooser. If change is needed, we could go another round. commit 9debffb5e0e42ff716f58b2270b3af09652294af Author: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Fri Mar 6 17:27:46 2020 -0800 Update README.md to remove dead link. See the conversation https://github.com/FreeRTOS/FreeRTOS/commit/42c627b2b88cb3b487fea983d8b566a8bbae54fa#comments . Linkage for both ```./FreeRTOS/Source``` and ```./FreeRTOS/Demo``` are removed, since it looks weird to only provide linkage to Demo. commit 7e1a4bf563240501fc45167aee9d929c533939dd Author: AniruddhaKanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Date: Fri Mar 6 15:18:09 2020 -0800 Fix DHCP option Client-identifier (#28) commit 42c627b2b88cb3b487fea983d8b566a8bbae54fa Author: Yuhui.Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Fri Mar 6 09:15:11 2020 -0800 Update readme and revert relative URL. (#27) * Reordering: bumping cloning instruction up. * Rewording readme.md to be clear kernel code is a submodule of this repository. * Reverting relative URL, since user cannot click through on GitHub page. (With URL, user could still download the correct version of the code. Reverting simply due to UI issue.) commit 5751ae9b60e248ebd0b4dd7c58df54364d2bb9d5 Author: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> Date: Fri Mar 6 09:11:42 2020 -0800 Update CORTEX_MPU_M33F_NXP_LPC55S69_MCUXpresso project (#26) This commit updates the project for LPC55S69 so that it works with the latest version of MCUXpresso and SDK. Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com> commit a9ffffe1f01f45f79e127c15727784984077932f Author: Carl Lundin <53273776+lundinc2@users.noreply.github.com> Date: Thu Mar 5 17:16:13 2020 -0800 Using Relative URL For Submoduling. (#24) commit 52c82076b38fe73d1dc46c97abf74ae9b803696c Author: Carl Lundin <53273776+lundinc2@users.noreply.github.com> Date: Thu Mar 5 09:16:31 2020 -0800 use relative path to point to bundled toolchain instead (#25) commit b877e4ec478de2c24d07ab46241070d7c66f375c Author: lundinc2 <53273776+lundinc2@users.noreply.github.com> Date: Tue Feb 25 13:18:38 2020 -0800 Moved vulnerability reporting and code of conduct to top of CONTRIBUTING.md (#20) commit bef165d46799fb8faa58aaa224f80c16b6538e69 Author: Yuhui.Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Tue Feb 18 22:06:38 2020 -0800 Linking test source file from relative path. (#19) commit 89e7bbe292afd3912d1f0b2402cc506878bad869 Author: Yuhui.Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Tue Feb 18 17:47:55 2020 -0800 A preliminary .gitignore file, to prevent us checking in files unnecessary. (#18) https://github.com/github/gitignore. commit c2a98127acb48c4562233230e66ca5c282688579 Author: RichardBarry <3073890+RichardBarry@users.noreply.github.com> Date: Sun Feb 16 13:19:53 2020 -0800 Minor wording changes in the 'previous releases' section of the readme.me file. (#17) commit 24c772d1439e5c291c0a29fce0a46996ca8afaa9 Author: Yuhui.Zheng <10982575+yuhui-zheng@users.noreply.github.com> Date: Fri Feb 14 12:47:01 2020 -0800 Submodule kernel directory. (#16) * Removing FreeRTOS/Source in readiness for submoduling. * Submoduling kernel. * README.md update due to submoduling. When releasing, please follow these steps: 1. in local directory, clean directory and check "git status" shows "nothing to commit, working tree clean" for ALL subdirectories. 2. copy source code and instructions only to an empty folder. Git related should not be in this folder -- this covers .git, .gitignore, .github, .gitmodules, gitmessages, ...... 3. zip the folder from step 2. (create both .zip and .7z) 4. attach .zip and .7z to the release. (e.g. attach these two in new release -- https://github.com/FreeRTOS/FreeRTOS/releases/new) 5. PLEASE download both, unzip, diff with your local git repo. (should not see any difference other than git related.) And, sanity check a couple of projects. commit c3f8b91652392dc55e0d7067b90a40de5f5f0837 Author: Rashed Talukder <9218468+rashedtalukder@users.noreply.github.com> Date: Thu Feb 13 17:47:14 2020 -0800 Update readme. Fixed typos and cli commands (#14) commit 4723b825f2989213c1cdb2ebf4d6793e0292e363 Author: Julian Poidevin <julian-poidevin@users.noreply.github.com> Date: Fri Feb 14 02:43:36 2020 +0100 Fixed wrong git clone SSH command (#13) Replaced bad https URL with proper SSH URL commit fc819b821715c42602819e58499846147a6394f5 Author: RichardBarry <3073890+RichardBarry@users.noreply.github.com> Date: Thu Feb 13 17:42:22 2020 -0800 Correct the xTimerCreate() documentation which said NULL was returned if the timer period was passed into the function as 0, whereas that is not the case. (#15) Add a note to the documentation for both the xTimerCreate() and xTimerCreateStatic() functions that the timer period must be greater than 0. commit 1c711ab530b5f0dbd811d7d62e0a3763706ffff4 Author: Rashed Talukder <9218468+rashedtalukder@users.noreply.github.com> Date: Wed Feb 12 23:00:18 2020 -0800 Updated contributions guidelines (#12) commit 84fcc0d5317d96c6b086034093c8c1c83e050819 Author: Cobus van Eeden <35851496+cobusve@users.noreply.github.com> Date: Wed Feb 12 15:05:06 2020 -0800 Updates to Markdown files and readme.txt (#11) commit 4b53196b71e02708ef1010a639d90236fbbd4032 Author: Cobus van Eeden <35851496+cobusve@users.noreply.github.com> Date: Tue Feb 11 18:23:08 2020 -0800 Adding Contributions.md (#8) git-svn-id: http://svn.code.sf.net/p/freertos/code/trunk@2825 1d2547de-c912-0410-9cb9-b8ca96c0e9e2
Diffstat (limited to 'FreeRTOS-Plus')
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c12
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c5
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c11
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c1061
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt81
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c180
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt12
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c89
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c194
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c12
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c75
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c65
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_declare.h38
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_dns_define.h48
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_tcp_define.h53
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_test_freertos_tcp.c362
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/uncrustify.cfg164
25 files changed, 1636 insertions, 842 deletions
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
index 7d8ed18c6..decd17338 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
index 930768055..59d55dea4 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
@@ -84,9 +84,9 @@
/* Offsets into the transmitted DHCP options fields at which various parameters
are located. */
-#define dhcpCLIENT_IDENTIFIER_OFFSET ( 5 )
-#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 13 )
-#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 19 )
+#define dhcpCLIENT_IDENTIFIER_OFFSET ( 6 )
+#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 14 )
+#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 20 )
/* Values used in the DHCP packets. */
#define dhcpREQUEST_OPCODE ( 1 )
@@ -905,7 +905,7 @@ static const uint8_t ucDHCPRequestOptions[] =
dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and
dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
- dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
+ dhcpCLIENT_IDENTIFIER_OPTION_CODE, 7, 1, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
dhcpOPTION_END_BYTE
@@ -943,7 +943,7 @@ static const uint8_t ucDHCPDiscoverOptions[] =
{
/* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */
dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
- dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
+ dhcpCLIENT_IDENTIFIER_OPTION_CODE, 7, 1, 0, 0, 0, 0, 0, 0, /* Client identifier. */
dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
dhcpOPTION_END_BYTE
};
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
index d4f167af1..ad0c3a4a0 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
index 48e632a01..707c99dc6 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
index 87099ecf1..bb68d2b38 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
index 0bda99317..855c9cbd3 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
index 849796508..70487b9d0 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
index 804088009..1c8f2246d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
index 14ae96e64..6d67c113a 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS+TCP V2.2.0
+ * FreeRTOS+TCP V2.2.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
@@ -280,7 +280,8 @@ UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
destinationAddress.sin_port = usPort;
destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
- if( xHandler( ( Socket_t ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
+ /* The value of 'xDataLength' was proven to be at least the size of a UDP packet in prvProcessIPPacket(). */
+ if( xHandler( ( Socket_t ) pxSocket, ( void* ) pcData, ( size_t ) ( pxNetworkBuffer->xDataLength - ipUDP_PAYLOAD_OFFSET_IPv4 ),
&xSourceAddress, &destinationAddress ) )
{
xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
index ebcbfbec9..5a605af9b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
@@ -305,7 +305,15 @@ static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
if( xBytesReceived < 0 )
{
/* This is an error. Logged. */
- FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d\n", xBytesReceived ) );
+ if( xBytesReceived == ETHER_ERR_LINK )
+ {
+ /* Auto-negotiation is not completed, and transmission/
+ reception is not enabled. Will be logged elsewhere. */
+ }
+ else
+ {
+ FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d not %d\n", xBytesReceived, ETHER_ERR_LINK ) );
+ }
}
else if( xBytesReceived > 0 )
{
@@ -452,7 +460,6 @@ void prvLinkStatusChange( BaseType_t xStatus )
{
if( xReportedStatus != xStatus )
{
- FreeRTOS_printf( ( "prvLinkStatusChange( %d )\n", xStatus ) );
xReportedStatus = xStatus;
}
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
index b9278c042..84019d637 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
@@ -44,26 +44,23 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "FreeRTOS_DNS.h"
+#include "FreeRTOS_ARP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
+#include "phyHandling.h"
/* ST includes. */
-#include "stm32f4xx_hal.h"
-
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004UL
-#endif
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#if defined( STM32F7xx )
+ #include "stm32f7xx_hal.h"
+#elif defined( STM32F4xx )
+ #include "stm32f4xx_hal.h"
+#elif defined( STM32F2xx )
+ #include "stm32f2xx_hal.h"
+#elif !defined( _lint ) /* Lint does not like an #error */
+ #error What part?
#endif
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
+#include "stm32fxx_hal_eth.h"
/* Interrupt events to process. Currently only the Rx event is processed
although code for other events is included to allow for possible future
@@ -78,77 +75,19 @@ expansion. */
ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-/* Naming and numbering of PHY registers. */
-#define PHY_REG_00_BMCR 0x00 /* Basic Mode Control Register */
-#define PHY_REG_01_BMSR 0x01 /* Basic Mode Status Register */
-#define PHY_REG_02_PHYSID1 0x02 /* PHYS ID 1 */
-#define PHY_REG_03_PHYSID2 0x03 /* PHYS ID 2 */
-#define PHY_REG_04_ADVERTISE 0x04 /* Advertisement control reg */
-
-#define PHY_ID_LAN8720 0x0007c0f0
-#define PHY_ID_DP83848I 0x20005C90
-
-#ifndef USE_STM324xG_EVAL
- #define USE_STM324xG_EVAL 1
+#ifndef niEMAC_HANDLER_TASK_PRIORITY
+ #define niEMAC_HANDLER_TASK_PRIORITY configMAX_PRIORITIES - 1
#endif
-#if( USE_STM324xG_EVAL == 0 )
- #define EXPECTED_PHY_ID PHY_ID_LAN8720
- #define PHY_REG_1F_PHYSPCS 0x1F /* 31 RW PHY Special Control Status */
- /* Use 3 bits in register 31 */
- #define PHYSPCS_SPEED_MASK 0x0C
- #define PHYSPCS_SPEED_10 0x04
- #define PHYSPCS_SPEED_100 0x08
- #define PHYSPCS_FULL_DUPLEX 0x10
-#else
- #define EXPECTED_PHY_ID PHY_ID_DP83848I
+#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
- #define PHY_REG_10_PHY_SR 0x10 /* PHY status register Offset */
- #define PHY_REG_19_PHYCR 0x19 /* 25 RW PHY Control Register */
+#if( ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) || ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) )
+ #warning Consider enabling checksum offloading
#endif
-/* Some defines used internally here to indicate preferences about speed, MDIX
-(wired direct or crossed), and duplex (half or full). */
-#define PHY_SPEED_10 1
-#define PHY_SPEED_100 2
-#define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
-
-#define PHY_MDIX_DIRECT 1
-#define PHY_MDIX_CROSSED 2
-#define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
-
-#define PHY_DUPLEX_HALF 1
-#define PHY_DUPLEX_FULL 2
-#define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
-
-#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
-
-/*
- * Description of all capabilities that can be advertised to
- * the peer (usually a switch or router).
- */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported. */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex. */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex. */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex. */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex. */
-
-#define ADVERTISE_ALL ( ADVERTISE_10HALF | ADVERTISE_10FULL | \
- ADVERTISE_100HALF | ADVERTISE_100FULL)
-
-/*
- * Value for the 'PHY_REG_00_BMCR', the PHY's Basic Mode Control Register
- */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex. */
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart. */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation. */
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps. */
-#define BMCR_RESET 0x8000 /* Reset the PHY. */
-
-#define PHYCR_MDIX_EN 0x8000 /* Enable Auto MDIX. */
-#define PHYCR_MDIX_FORCE 0x4000 /* Force MDIX crossed. */
-
-#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
+#ifndef niDESCRIPTOR_WAIT_TIME_MS
+ #define niDESCRIPTOR_WAIT_TIME_MS 250uL
+#endif
/*
* Most users will want a PHY that negotiates about
@@ -191,6 +130,31 @@ FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
#endif
+/* Two choices must be made: RMII versus MII,
+and the index of the PHY in use ( between 0 and 31 ). */
+#ifndef ipconfigUSE_RMII
+ #ifdef STM32F7xx
+ #define ipconfigUSE_RMII 1
+ #else
+ #define ipconfigUSE_RMII 0
+ #endif /* STM32F7xx */
+#endif /* ipconfigUSE_RMII */
+
+#if( ipconfigUSE_RMII != 0 )
+ #warning Using RMII, make sure if this is correct
+#else
+ #warning Using MII, make sure if this is correct
+#endif
+
+typedef enum
+{
+ eMACInit, /* Must initialise MAC. */
+ eMACPass, /* Initialisation was successful. */
+ eMACFailed, /* Initialisation failed. */
+} eMAC_INIT_STATUS_TYPE;
+
+static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
+
/*-----------------------------------------------------------*/
/*
@@ -231,43 +195,30 @@ static void prvDMATxDescListInit( void );
*/
static void prvDMARxDescListInit( void );
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* After packets have been sent, the network
- buffers will be released. */
- static void vClearTXBuffers( void );
-#endif /* ipconfigZERO_COPY_TX_DRIVER */
+/* After packets have been sent, the network
+buffers will be released. */
+static void vClearTXBuffers( void );
/*-----------------------------------------------------------*/
-typedef struct _PhyProperties_t
-{
- uint8_t speed;
- uint8_t mdix;
- uint8_t duplex;
- uint8_t spare;
-} PhyProperties_t;
-
/* Bit map of outstanding ETH interrupt events for processing. Currently only
the Rx interrupt is handled, although code is included for other events to
enable future expansion. */
static volatile uint32_t ulISREvents;
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-
#if( ipconfigUSE_LLMNR == 1 )
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
#endif
+static EthernetPhy_t xPhyObject;
+
/* Ethernet handle. */
static ETH_HandleTypeDef xETH;
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* xTXDescriptorSemaphore is a counting semaphore with
- a maximum count of ETH_TXBUFNB, which is the number of
- DMA TX descriptors. */
- static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-#endif /* ipconfigZERO_COPY_TX_DRIVER */
+/* xTXDescriptorSemaphore is a counting semaphore with
+a maximum count of ETH_TXBUFNB, which is the number of
+DMA TX descriptors. */
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
/*
* Note: it is adviced to define both
@@ -282,30 +233,39 @@ static ETH_HandleTypeDef xETH;
* TX buffers are allocated in a zero-copy driver.
*/
/* MAC buffers: ---------------------------------------------------------*/
-__ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ] __ALIGN_END;/* Ethernet Rx MA Descriptor */
-#if( ipconfigZERO_COPY_RX_DRIVER == 0 )
- __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END; /* Ethernet Receive Buffer */
-#endif
-__ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ] __ALIGN_END;/* Ethernet Tx DMA Descriptor */
-#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END; /* Ethernet Transmit Buffer */
+/* Put the DMA descriptors in '.first_data'.
+This is important for STM32F7, which has an L1 data cache.
+The first 64KB of the SRAM is not cached.
+See README.TXT in this folder. */
+
+/* Ethernet Rx MA Descriptor */
+__attribute__ ((aligned (32)))
+#if defined(STM32F7xx)
+ __attribute__ ((section(".first_data")))
#endif
+ ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ];
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* DMATxDescToClear points to the next TX DMA descriptor
- that must be cleared by vClearTXBuffers(). */
- static __IO ETH_DMADescTypeDef *DMATxDescToClear;
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 )
+ /* Ethernet Receive Buffer */
+ __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;
#endif
-/* Value to be written into the 'Basic mode Control Register'. */
-static uint32_t ulBCRvalue;
+/* Ethernet Tx DMA Descriptor */
+__attribute__ ((aligned (32)))
+#if defined(STM32F7xx)
+ __attribute__ ((section(".first_data")))
+#endif
+ ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ];
-/* Value to be written into the 'Advertisement Control Register'. */
-static uint32_t ulACRValue;
+#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ /* Ethernet Transmit Buffer */
+ __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;
+#endif
-/* ucMACAddress as it appears in main.c */
-extern const uint8_t ucMACAddress[ 6 ];
+/* DMATxDescToClear points to the next TX DMA descriptor
+that must be cleared by vClearTXBuffers(). */
+static __IO ETH_DMADescTypeDef *DMATxDescToClear;
/* Holds the handle of the task used as a deferred interrupt processor. The
handle is used so direct notifications can be sent to the task for all EMAC/DMA
@@ -316,28 +276,28 @@ static TaskHandle_t xEMACTaskHandle = NULL;
const PhyProperties_t xPHYProperties =
{
#if( ipconfigETHERNET_AN_ENABLE != 0 )
- .speed = PHY_SPEED_AUTO,
- .duplex = PHY_DUPLEX_AUTO,
+ .ucSpeed = PHY_SPEED_AUTO,
+ .ucDuplex = PHY_DUPLEX_AUTO,
#else
#if( ipconfigETHERNET_USE_100MB != 0 )
- .speed = PHY_SPEED_100,
+ .ucSpeed = PHY_SPEED_100,
#else
- .speed = PHY_SPEED_10,
+ .ucSpeed = PHY_SPEED_10,
#endif
#if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
- .duplex = PHY_DUPLEX_FULL,
+ .ucDuplex = PHY_DUPLEX_FULL,
#else
- .duplex = PHY_DUPLEX_HALF,
+ .ucDuplex = PHY_DUPLEX_HALF,
#endif
#endif
#if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )
- .mdix = PHY_MDIX_AUTO,
+ .ucMDI_X = PHY_MDIX_AUTO,
#elif( ipconfigETHERNET_CROSSED_LINK != 0 )
- .mdix = PHY_MDIX_CROSSED,
+ .ucMDI_X = PHY_MDIX_CROSSED,
#else
- .mdix = PHY_MDIX_DIRECT,
+ .ucMDI_X = PHY_MDIX_DIRECT,
#endif
};
@@ -347,6 +307,8 @@ void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ ( void ) heth;
+
/* Ethernet RX-Complete callback function, elsewhere declared as weak. */
ulISREvents |= EMAC_IF_RX_EVENT;
/* Wakeup the prvEMACHandlerTask. */
@@ -358,46 +320,46 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
}
/*-----------------------------------------------------------*/
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
- {
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- /* This call-back is only useful in case packets are being sent
- zero-copy. Once they're sent, the buffers will be released
- by the function vClearTXBuffers(). */
- ulISREvents |= EMAC_IF_TX_EVENT;
- /* Wakeup the prvEMACHandlerTask. */
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
+void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
+{
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- }
-#endif /* ipconfigZERO_COPY_TX_DRIVER */
+ ( void ) heth;
+ /* This call-back is only useful in case packets are being sent
+ zero-copy. Once they're sent, the buffers will be released
+ by the function vClearTXBuffers(). */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ /* Wakeup the prvEMACHandlerTask. */
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ }
+}
/*-----------------------------------------------------------*/
+static void vClearTXBuffers()
+{
+__IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
+size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- static void vClearTXBuffers()
- {
- __IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
NetworkBufferDescriptor_t *pxNetworkBuffer;
uint8_t *ucPayLoad;
- size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+#endif
- /* This function is called after a TX-completion interrupt.
- It will release each Network Buffer used in xNetworkInterfaceOutput().
- 'uxCount' represents the number of descriptors given to DMA for transmission.
- After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
- while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
+ /* This function is called after a TX-completion interrupt.
+ It will release each Network Buffer used in xNetworkInterfaceOutput().
+ 'uxCount' represents the number of descriptors given to DMA for transmission.
+ After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
+ while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
+ {
+ if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
+ {
+ break;
+ }
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
{
- if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
- {
- break;
- }
-
ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
if( ucPayLoad != NULL )
@@ -409,15 +371,16 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
}
DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;
}
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
- DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
+ DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
}
-#endif /* ipconfigZERO_COPY_TX_DRIVER */
+}
/*-----------------------------------------------------------*/
BaseType_t xNetworkInterfaceInitialise( void )
@@ -425,90 +388,117 @@ BaseType_t xNetworkInterfaceInitialise( void )
HAL_StatusTypeDef hal_eth_init_status;
BaseType_t xResult;
- if( xEMACTaskHandle == NULL )
+ if( xMacInitStatus == eMACInit )
{
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
+ if( xTXDescriptorSemaphore == NULL )
{
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
- configASSERT( xTXDescriptorSemaphore );
- }
+ xMacInitStatus = eMACFailed;
}
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ else
+ {
+ /* Initialise ETH */
- /* Initialise ETH */
+ xETH.Instance = ETH;
+ xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
+ xETH.Init.Speed = ETH_SPEED_100M;
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
+ /* Value of PhyAddress doesn't matter, will be probed for. */
+ xETH.Init.PhyAddress = 0;
- xETH.Instance = ETH;
- xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
- xETH.Init.Speed = ETH_SPEED_100M;
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- xETH.Init.PhyAddress = 1;
+ xETH.Init.MACAddr = ( uint8_t * ) FreeRTOS_GetMACAddress();
+ xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
- xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;
- xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ /* using the ETH_CHECKSUM_BY_HARDWARE option:
+ both the IP and the protocol checksums will be calculated
+ by the peripheral. */
+ xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
+ }
+ #else
+ {
+ xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
+ }
+ #endif
- /* using the ETH_CHECKSUM_BY_HARDWARE option:
- both the IP and the protocol checksums will be calculated
- by the peripheral. */
- xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
+ #if( ipconfigUSE_RMII != 0 )
+ {
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
+ }
+ #else
+ {
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
+ }
+ #endif /* ipconfigUSE_RMII */
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
- hal_eth_init_status = HAL_ETH_Init( &xETH );
+ hal_eth_init_status = HAL_ETH_Init( &xETH );
- /* Only for inspection by debugger. */
- ( void ) hal_eth_init_status;
+ /* Only for inspection by debugger. */
+ ( void ) hal_eth_init_status;
- /* Set the TxDesc and RxDesc pointers. */
- xETH.TxDesc = DMATxDscrTab;
- xETH.RxDesc = DMARxDscrTab;
+ /* Set the TxDesc and RxDesc pointers. */
+ xETH.TxDesc = DMATxDscrTab;
+ xETH.RxDesc = DMARxDscrTab;
- /* Make sure that all unused fields are cleared. */
- memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
- memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
+ /* Make sure that all unused fields are cleared. */
+ memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
+ memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
/* Initialize Tx Descriptors list: Chain Mode */
DMATxDescToClear = DMATxDscrTab;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- /* Initialise TX-descriptors. */
- prvDMATxDescListInit();
+ /* Initialise TX-descriptors. */
+ prvDMATxDescListInit();
- /* Initialise RX-descriptors. */
- prvDMARxDescListInit();
+ /* Initialise RX-descriptors. */
+ prvDMARxDescListInit();
- #if( ipconfigUSE_LLMNR != 0 )
- {
- /* Program the LLMNR address at index 1. */
- prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
- }
- #endif
+ #if( ipconfigUSE_LLMNR != 0 )
+ {
+ /* Program the LLMNR address at index 1. */
+ prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
+ }
+ #endif
- /* Force a negotiation with the Switch or Router and wait for LS. */
- prvEthernetUpdateConfig( pdTRUE );
+ /* Force a negotiation with the Switch or Router and wait for LS. */
+ prvEthernetUpdateConfig( pdTRUE );
- /* The deferred interrupt handler task is created at the highest
- possible priority to ensure the interrupt handler can return directly
- to it. The task's handle is stored in xEMACTaskHandle so interrupts can
- notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ /* The deferred interrupt handler task is created at the highest
+ possible priority to ensure the interrupt handler can return directly
+ to it. The task's handle is stored in xEMACTaskHandle so interrupts can
+ notify the task when there is something to process. */
+ if( xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle ) == pdPASS )
+ {
+ /* The xTXDescriptorSemaphore and the task are created successfully. */
+ xMacInitStatus = eMACPass;
+ }
+ else
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ }
} /* if( xEMACTaskHandle == NULL ) */
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ if( xMacInitStatus != eMACPass )
{
- xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
- xResult = pdPASS;
- FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
+ /* EMAC initialisation failed, return pdFAIL. */
+ xResult = pdFAIL;
}
else
{
- /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
- and it will keep on checking the PHY and set ulPHYLinkStatus when necessary. */
- xResult = pdFAIL;
- FreeRTOS_printf( ( "Link Status still low\n" ) ) ;
+ if( xPhyObject.ulLinkStatusMask != 0uL )
+ {
+ xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
+ xResult = pdPASS;
+ FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
+ }
+ else
+ {
+ /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
+ and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
+ xResult = pdFAIL;
+ }
}
/* When returning non-zero, the stack will become active and
start DHCP (in configured) */
@@ -542,6 +532,10 @@ BaseType_t xIndex;
/* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
}
+ else
+ {
+ pxDMADescriptor->Status &= ~( ( uint32_t ) ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL );
+ }
/* Initialize the next descriptor with the Next Descriptor Polling Enable */
if( xIndex < ETH_TXBUFNB - 1 )
@@ -625,6 +619,8 @@ static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8
{
uint32_t ulTempReg;
+ ( void ) heth;
+
/* Calculate the selected MAC address high register. */
ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
@@ -647,46 +643,38 @@ __IO ETH_DMADescTypeDef *pxDmaTxDesc;
/* Do not wait too long for a free TX DMA buffer. */
const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ /* Open a do {} while ( 0 ) loop to be able to call break. */
+ do
{
- ProtocolPacket_t *pxPacket;
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ ProtocolPacket_t *pxPacket;
- /* If the peripheral must calculate the checksum, it wants
- the protocol checksum to have a value of zero. */
- pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
+ /* If the peripheral must calculate the checksum, it wants
+ the protocol checksum to have a value of zero. */
+ pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
- if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
- {
- pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
+ if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
+ {
+ pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
+ }
}
- }
- #endif
-
- /* Open a do {} while ( 0 ) loop to be able to call break. */
- do
- {
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ #endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */
+ if( xPhyObject.ulLinkStatusMask != 0 )
{
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
{
- if( xTXDescriptorSemaphore == NULL )
- {
- break;
- }
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- break;
- }
+ /* Time-out waiting for a free TX descriptor. */
+ break;
}
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
/* This function does the actual transmission of the packet. The packet is
contained in 'pxDescriptor' that is passed to the function. */
pxDmaTxDesc = xETH.TxDesc;
/* Is this buffer available? */
- if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 )
+ configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );
+
{
/* Is this buffer available? */
/* Get bytes in current buffer. */
@@ -701,32 +689,54 @@ const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
{
/* Copy the bytes. */
memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL;
}
#else
{
+ configASSERT( bReleaseAfterSend != 0 );
+
/* Move the buffer. */
pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
- /* Ask to set the IPv4 checksum.
- Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
/* The Network Buffer has been passed to DMA, no need to release it. */
bReleaseAfterSend = pdFALSE_UNSIGNED;
}
#endif /* ipconfigZERO_COPY_TX_DRIVER */
+ /* Ask to set the IPv4 checksum.
+ Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
+ }
+ #else
+ {
+ pxDmaTxDesc->Status &= ~( ( uint32_t ) ETH_DMATXDESC_CIC );
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_IC;
+ }
+ #endif
+
+
/* Prepare transmit descriptors to give to DMA. */
/* Set LAST and FIRST segment */
pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
/* Set frame size */
pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
+
+ #if( NETWORK_BUFFERS_CACHED != 0 )
+ {
+ BaseType_t xlength = CACHE_LINE_SIZE * ( ( ulTransmitSize + NETWORK_BUFFER_HEADER_SIZE + CACHE_LINE_SIZE - 1 ) / CACHE_LINE_SIZE );
+ uint32_t *pulBuffer = ( uint32_t )( pxDescriptor->pucEthernetBuffer - NETWORK_BUFFER_HEADER_SIZE );
+ cache_clean_invalidate_by_addr( pulBuffer, xlength );
+ }
+ #endif
+
/* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
/* Point to next descriptor */
xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );
-
+ /* Ensure completion of memory access */
+ __DSB();
/* Resume DMA transmission*/
xETH.Instance->DMATPDR = 0;
iptraceNETWORK_INTERFACE_TRANSMIT();
@@ -801,20 +811,24 @@ const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
{
- uint16_t port = pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort;
+ uint16_t usSourcePort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort );
+ uint16_t usDestinationPort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort );
- if( ( xPortHasUDPSocket( port ) == pdFALSE )
+ if( ( xPortHasUDPSocket( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort ) == pdFALSE )
#if ipconfigUSE_LLMNR == 1
- && ( port != FreeRTOS_ntohs( ipLLMNR_PORT ) )
+ && ( usDestinationPort != ipLLMNR_PORT )
+ && ( usSourcePort != ipLLMNR_PORT )
#endif
#if ipconfigUSE_NBNS == 1
- && ( port != FreeRTOS_ntohs( ipNBNS_PORT ) )
+ && ( usDestinationPort != ipNBNS_PORT )
+ && ( usSourcePort != ipNBNS_PORT )
#endif
#if ipconfigUSE_DNS == 1
- && ( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort != FreeRTOS_ntohs( ipDNS_PORT ) )
+ && ( usSourcePort != ipDNS_PORT )
#endif
) {
/* Drop this packet, not for this device. */
+ FreeRTOS_printf( ( "Drop: UDP port %d -> %d\n", usSourcePort, usDestinationPort ) );
return pdFALSE;
}
}
@@ -824,20 +838,59 @@ const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
}
/*-----------------------------------------------------------*/
+static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
+{
+IPStackEvent_t xRxEvent;
+
+ xRxEvent.eEventType = eNetworkRxEvent;
+ xRxEvent.pvData = ( void * ) pxDescriptor;
+
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
+ {
+ /* The buffer could not be sent to the stack so must be released again.
+ This is a deferred handler taskr, not a real interrupt, so it is ok to
+ use the task level function here. */
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ do
+ {
+ NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ pxDescriptor = pxNext;
+ } while( pxDescriptor != NULL );
+ }
+ #else
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
+ }
+ else
+ {
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+}
+
static BaseType_t prvNetworkInterfaceInput( void )
{
NetworkBufferDescriptor_t *pxCurDescriptor;
NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
-BaseType_t xReceivedLength, xAccepted;
+#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
+ NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
+#endif
+BaseType_t xReceivedLength = 0;
__IO ETH_DMADescTypeDef *pxDMARxDescriptor;
-xIPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( niDESCRIPTOR_WAIT_TIME_MS );
uint8_t *pucBuffer;
pxDMARxDescriptor = xETH.RxDesc;
- if( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN) == 0 )
+ while( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0u )
{
+ BaseType_t xAccepted = pdTRUE;
/* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
@@ -847,18 +900,13 @@ uint8_t *pucBuffer;
/* Chained Mode */
/* Selects the next DMA Rx descriptor list for next buffer to read */
xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
- }
- else
- {
- xReceivedLength = 0;
- }
- /* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
- /* In order to make the code easier and faster, only packets in a single buffer
- will be accepted. This can be done by making the buffers large enough to
- hold a complete Ethernet packet (1536 bytes). */
- if( xReceivedLength > 0ul && xReceivedLength < ETH_RX_BUF_SIZE )
- {
+ /* In order to make the code easier and faster, only packets in a single buffer
+ will be accepted. This can be done by making the buffers large enough to
+ hold a complete Ethernet packet (1536 bytes).
+ Therefore, two sanity checks: */
+ configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
+
if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
{
/* Not an Ethernet frame-type or a checmsum error. */
@@ -904,20 +952,28 @@ uint8_t *pucBuffer;
if( xAccepted != pdFALSE )
{
pxCurDescriptor->xDataLength = xReceivedLength;
- xRxEvent.pvData = ( void * ) pxCurDescriptor;
-
- /* Pass the data to the TCP/IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- /* Could not send the descriptor into the TCP/IP stack, it
- must be released. */
- vReleaseNetworkBufferAndDescriptor( pxCurDescriptor );
- iptraceETHERNET_RX_EVENT_LOST();
+ pxCurDescriptor->pxNextBuffer = NULL;
+
+ if( pxFirstDescriptor == NULL )
+ {
+ // Becomes the first message
+ pxFirstDescriptor = pxCurDescriptor;
+ }
+ else if( pxLastDescriptor != NULL )
+ {
+ // Add to the tail
+ pxLastDescriptor->pxNextBuffer = pxCurDescriptor;
+ }
+
+ pxLastDescriptor = pxCurDescriptor;
}
- else
+ #else
{
- iptraceNETWORK_INTERFACE_RECEIVE();
+ prvPassEthMessages( pxCurDescriptor );
}
+ #endif
}
/* Release descriptors to DMA */
@@ -940,6 +996,8 @@ uint8_t *pucBuffer;
pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;
+ /* Ensure completion of memory access */
+ __DSB();
/* When Rx Buffer unavailable flag is set clear it and resume
reception. */
if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )
@@ -950,311 +1008,138 @@ uint8_t *pucBuffer;
/* Resume DMA reception. */
xETH.Instance->DMARPDR = 0;
}
+ pxDMARxDescriptor = xETH.RxDesc;
}
- return ( xReceivedLength > 0 );
-}
-/*-----------------------------------------------------------*/
-
-void vMACBProbePhy( void )
-{
-uint32_t ulConfig, ulAdvertise, ulLower, ulUpper, ulMACPhyID, ulValue;
-TimeOut_t xPhyTime;
-TickType_t xRemTime = 0;
-#if( EXPECTED_PHY_ID == PHY_ID_DP83848I )
- uint32_t ulPhyControl;
-#endif
-
- HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_03_PHYSID2, &ulLower);
- HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_02_PHYSID1, &ulUpper);
-
- ulMACPhyID = ( ( ulUpper << 16 ) & 0xFFFF0000 ) | ( ulLower & 0xFFF0 );
-
- /* The expected ID for the 'LAN8720' is 0x0007c0f0. */
- /* The expected ID for the 'DP83848I' is 0x20005C90. */
-
- FreeRTOS_printf( ( "PHY ID %lX (%s)\n", ulMACPhyID,
- ( ulMACPhyID == EXPECTED_PHY_ID ) ? "OK" : "Unknown" ) );
-
- /* Remove compiler warning if FreeRTOS_printf() is not defined. */
- ( void ) ulMACPhyID;
-
- /* Set advertise register. */
- if( ( xPHYProperties.speed == PHY_SPEED_AUTO ) && ( xPHYProperties.duplex == PHY_DUPLEX_AUTO ) )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- ulAdvertise = ADVERTISE_CSMA | ADVERTISE_ALL;
- /* Reset auto-negotiation capability. */
- }
- else
- {
- ulAdvertise = ADVERTISE_CSMA;
-
- if( xPHYProperties.speed == PHY_SPEED_AUTO )
- {
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
- {
- ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_100FULL;
- }
- else
- {
- ulAdvertise |= ADVERTISE_10HALF | ADVERTISE_100HALF;
- }
- }
- else if( xPHYProperties.duplex == PHY_DUPLEX_AUTO )
+ if( pxFirstDescriptor != NULL )
{
- if( xPHYProperties.speed == PHY_SPEED_10 )
- {
- ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_10HALF;
- }
- else
- {
- ulAdvertise |= ADVERTISE_100FULL | ADVERTISE_100HALF;
- }
- }
- else if( xPHYProperties.speed == PHY_SPEED_100 )
- {
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
- {
- ulAdvertise |= ADVERTISE_100FULL;
- }
- else
- {
- ulAdvertise |= ADVERTISE_100HALF;
- }
- }
- else
- {
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
- {
- ulAdvertise |= ADVERTISE_10FULL;
- }
- else
- {
- ulAdvertise |= ADVERTISE_10HALF;
- }
+ prvPassEthMessages( pxFirstDescriptor );
}
}
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- /* Read Control register. */
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );
-
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig | BMCR_RESET );
- xRemTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );
- vTaskSetTimeOutState( &xPhyTime );
+ return ( xReceivedLength > 0 );
+}
+/*-----------------------------------------------------------*/
- for( ; ; )
- {
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulValue );
- if( ( ulValue & BMCR_RESET ) == 0 )
- {
- FreeRTOS_printf( ( "BMCR_RESET ready\n" ) );
- break;
- }
- if( xTaskCheckForTimeOut( &xPhyTime, &xRemTime ) != pdFALSE )
- {
- FreeRTOS_printf( ( "BMCR_RESET timed out\n" ) );
- break;
- }
- }
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig & ~BMCR_RESET );
- vTaskDelay( pdMS_TO_TICKS( 50ul ) );
+BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )
+{
+uint16_t usPrevAddress = xETH.Init.PhyAddress;
+BaseType_t xResult;
+HAL_StatusTypeDef xHALResult;
- /* Write advertise register. */
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulAdvertise );
+ xETH.Init.PhyAddress = xAddress;
+ xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );
+ xETH.Init.PhyAddress = usPrevAddress;
- /*
- AN_EN AN1 AN0 Forced Mode
- 0 0 0 10BASE-T, Half-Duplex
- 0 0 1 10BASE-T, Full-Duplex
- 0 1 0 100BASE-TX, Half-Duplex
- 0 1 1 100BASE-TX, Full-Duplex
- AN_EN AN1 AN0 Advertised Mode
- 1 0 0 10BASE-T, Half/Full-Duplex
- 1 0 1 100BASE-TX, Half/Full-Duplex
- 1 1 0 10BASE-T Half-Duplex
- 100BASE-TX, Half-Duplex
- 1 1 1 10BASE-T, Half/Full-Duplex
- 100BASE-TX, Half/Full-Duplex
- */
-
- /* Read Control register. */
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );
-
- ulConfig &= ~( BMCR_ANRESTART | BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX );
-
- /* HT 12/9/14: always set AN-restart and AN-enable, even though the choices
- are limited. */
- ulConfig |= (BMCR_ANRESTART | BMCR_ANENABLE);
-
- if( xPHYProperties.speed == PHY_SPEED_100 )
+ if( xHALResult == HAL_OK )
{
- ulConfig |= BMCR_SPEED100;
+ xResult = 0;
}
- else if( xPHYProperties.speed == PHY_SPEED_10 )
+ else
{
- ulConfig &= ~BMCR_SPEED100;
+ xResult = -1;
}
+ return xResult;
+}
+/*-----------------------------------------------------------*/
- if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
- {
- ulConfig |= BMCR_FULLDPLX;
- }
- else if( xPHYProperties.duplex == PHY_DUPLEX_HALF )
- {
- ulConfig &= ~BMCR_FULLDPLX;
- }
+BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )
+{
+uint16_t usPrevAddress = xETH.Init.PhyAddress;
+BaseType_t xResult;
+HAL_StatusTypeDef xHALResult;
+
+ xETH.Init.PhyAddress = xAddress;
+ xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );
+ xETH.Init.PhyAddress = usPrevAddress;
- #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )
+ if( xHALResult == HAL_OK )
{
+ xResult = 0;
}
- #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )
+ else
{
- /* Read PHY Control register. */
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_19_PHYCR, &ulPhyControl );
-
- /* Clear bits which might get set: */
- ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );
-
- if( xPHYProperties.mdix == PHY_MDIX_AUTO )
- {
- ulPhyControl |= PHYCR_MDIX_EN;
- }
- else if( xPHYProperties.mdix == PHY_MDIX_CROSSED )
- {
- /* Force direct link = Use crossed RJ45 cable. */
- ulPhyControl &= ~PHYCR_MDIX_FORCE;
- }
- else
- {
- /* Force crossed link = Use direct RJ45 cable. */
- ulPhyControl |= PHYCR_MDIX_FORCE;
- }
- /* update PHY Control Register. */
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_19_PHYCR, ulPhyControl );
+ xResult = -1;
}
- #endif
- FreeRTOS_printf( ( "+TCP: advertise: %lX config %lX\n", ulAdvertise, ulConfig ) );
+ return xResult;
+}
+/*-----------------------------------------------------------*/
- /* Now the two values to global values for later use. */
- ulBCRvalue = ulConfig;
- ulACRValue = ulAdvertise;
+void vMACBProbePhy( void )
+{
+ vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
+ xPhyDiscover( &xPhyObject );
+ xPhyConfigure( &xPhyObject, &xPHYProperties );
}
/*-----------------------------------------------------------*/
static void prvEthernetUpdateConfig( BaseType_t xForce )
{
-__IO uint32_t ulTimeout = 0;
-uint32_t ulRegValue = 0;
-
- FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS %d Force %d\n",
- ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ,
- xForce ) );
+ FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02lX Force %d\n",
+ xPhyObject.ulLinkStatusMask,
+ ( int )xForce ) );
- if( ( xForce != pdFALSE ) || ( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) )
+ if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )
{
/* Restart the auto-negotiation. */
if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )
{
- /* Enable Auto-Negotiation. */
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue | BMCR_ANRESTART );
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulACRValue);
+ xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );
- /* Wait until the auto-negotiation will be completed */
- do
+ /* Configure the MAC with the Duplex Mode fixed by the
+ auto-negotiation process. */
+ if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )
{
- ulTimeout++;
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue );
- } while( ( ( ulRegValue & PHY_AUTONEGO_COMPLETE) == 0 ) && ( ulTimeout < PHY_READ_TO ) );
-
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue & ~BMCR_ANRESTART );
-
- if( ulTimeout < PHY_READ_TO )
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
+ }
+ else
{
- /* Reset Timeout counter. */
- ulTimeout = 0;
-
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue);
- if( ( ulRegValue & BMSR_LINK_STATUS ) != 0 )
- {
- ulPHYLinkStatus |= BMSR_LINK_STATUS;
- }
- else
- {
- ulPHYLinkStatus &= ~( BMSR_LINK_STATUS );
- }
-
- #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )
- {
- /* 31 RW PHY Special Control Status */
- uint32_t ulControlStatus;
-
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_1F_PHYSPCS, &ulControlStatus);
- ulRegValue = 0;
- if( ( ulControlStatus & PHYSPCS_FULL_DUPLEX ) != 0 )
- {
- ulRegValue |= PHY_DUPLEX_STATUS;
- }
- if( ( ulControlStatus & PHYSPCS_SPEED_MASK ) == PHYSPCS_SPEED_10 )
- {
- ulRegValue |= PHY_SPEED_STATUS;
- }
-
- }
- #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )
- {
- /* Read the result of the auto-negotiation. */
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_10_PHY_SR, &ulRegValue);
- }
- #endif
- FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",
- ulRegValue,
- (ulRegValue & PHY_DUPLEX_STATUS) ? "full" : "half",
- (ulRegValue & PHY_SPEED_STATUS) ? 10 : 100,
- ((ulPHYLinkStatus |= BMSR_LINK_STATUS) != 0) ? "high" : "low" ) );
-
- /* Configure the MAC with the Duplex Mode fixed by the
- auto-negotiation process. */
- if( ( ulRegValue & PHY_DUPLEX_STATUS ) != ( uint32_t ) RESET )
- {
- /* Set Ethernet duplex mode to Full-duplex following the
- auto-negotiation. */
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- }
- else
- {
- /* Set Ethernet duplex mode to Half-duplex following the
- auto-negotiation. */
- xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
- }
+ xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
+ }
- /* Configure the MAC with the speed fixed by the
- auto-negotiation process. */
- if( ( ulRegValue & PHY_SPEED_STATUS) != 0 )
- {
- /* Set Ethernet speed to 10M following the
- auto-negotiation. */
- xETH.Init.Speed = ETH_SPEED_10M;
- }
- else
- {
- /* Set Ethernet speed to 100M following the
- auto-negotiation. */
- xETH.Init.Speed = ETH_SPEED_100M;
- }
- } /* if( ulTimeout < PHY_READ_TO ) */
+ /* Configure the MAC with the speed fixed by the
+ auto-negotiation process. */
+ if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )
+ {
+ xETH.Init.Speed = ETH_SPEED_10M;
+ }
+ else
+ {
+ xETH.Init.Speed = ETH_SPEED_100M;
+ }
}
else /* AutoNegotiation Disable */
{
- uint16_t usValue;
-
/* Check parameters */
assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );
assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );
- /* Set MAC Speed and Duplex Mode to PHY */
- usValue = ( uint16_t ) ( xETH.Init.DuplexMode >> 3 ) | ( uint16_t ) ( xETH.Init.Speed >> 1 );
- HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, usValue );
+ if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )
+ {
+ xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;
+ }
+ else
+ {
+ xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;
+ }
+
+ if( xETH.Init.Speed == ETH_SPEED_10M )
+ {
+ xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;
+ }
+ else
+ {
+ xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;
+ }
+
+ xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;
+
+ /* Use predefined (fixed) configuration. */
+ xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );
}
/* ETHERNET MAC Re-Configuration */
@@ -1275,7 +1160,7 @@ BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xReturn;
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ if( xPhyObject.ulLinkStatusMask != 0 )
{
xReturn = pdPASS;
}
@@ -1288,27 +1173,43 @@ BaseType_t xReturn;
}
/*-----------------------------------------------------------*/
+/* Uncomment this in case BufferAllocation_1.c is used. */
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+static
+#if defined(STM32F7xx)
+ __attribute__ ((section(".first_data")))
+#endif
+ uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * ETH_MAX_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
+uint8_t *ucRAMBuffer = ucNetworkPackets;
+uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += ETH_MAX_PACKET_SIZE;
+ }
+}
+/*-----------------------------------------------------------*/
+
static void prvEMACHandlerTask( void *pvParameters )
{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
UBaseType_t uxLastMinBufferCount = 0;
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
UBaseType_t uxLastMinQueueSpace = 0;
#endif
UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t xStatus;
+BaseType_t xResult;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
/* Remove compiler warnings about unused parameters. */
( void ) pvParameters;
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
for( ;; )
{
+ xResult = 0;
uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
if( uxLastMinBufferCount != uxCurrentCount )
{
@@ -1319,7 +1220,6 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
}
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
if( xTXDescriptorSemaphore != NULL )
{
static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
@@ -1332,7 +1232,7 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
}
}
- #endif
+
#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
{
uxCurrentCount = uxGetMinimumIPQueueSpace();
@@ -1357,24 +1257,14 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
ulISREvents &= ~EMAC_IF_RX_EVENT;
xResult = prvNetworkInterfaceInput();
- if( xResult > 0 )
- {
- while( prvNetworkInterfaceInput() > 0 )
- {
- }
- }
}
if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
{
/* Code to release TX buffers if zero-copy is used. */
ulISREvents &= ~EMAC_IF_TX_EVENT;
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Check if DMA packets have been delivered. */
- vClearTXBuffers();
- }
- #endif
+ /* Check if DMA packets have been delivered. */
+ vClearTXBuffers();
}
if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
@@ -1382,34 +1272,10 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
/* Future extension: logging about errors that occurred. */
ulISREvents &= ~EMAC_IF_ERR_EVENT;
}
-
- if( xResult > 0 )
+ if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )
{
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &xStatus );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- prvEthernetUpdateConfig( pdFALSE );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
+ /* Something has changed to a Link Status, need re-check. */
+ prvEthernetUpdateConfig( pdFALSE );
}
}
}
@@ -1419,3 +1285,4 @@ void ETH_IRQHandler( void )
{
HAL_ETH_IRQHandler( &xETH );
}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
new file mode 100644
index 000000000..1d244bae7
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
@@ -0,0 +1,81 @@
+This is a FreeeRTOS+TCP driver that works for both STM32F4xx and STM32F7xx parts.
+
+The code of stm32fxx_hal_eth.c is based on both drivers as provided by ST.
+
+These modules should be included:
+
+ NetworkInterface.c
+ stm32fxx_hal_eth.c
+
+It is assumed that one of these words are defined:
+
+ STM32F7xx
+ STM32F407xx
+ STM32F417xx
+ STM32F427xx
+ STM32F437xx
+ STM32F429xx
+ STM32F439xx
+
+The driver has been tested on both Eval and Discovery boards with both STM32F4 and STM32F7.
+
+Recommended settings for STM32Fxx Network Interface:
+
+// Defined in FreeRTOSIPConfig.h
+
+#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
+#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
+#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
+#define ipconfigZERO_COPY_RX_DRIVER 1
+#define ipconfigZERO_COPY_TX_DRIVER 1
+#define ipconfigUSE_LINKED_RX_MESSAGES 1
+
+// Defined in stm32f4xx_hal_conf.h
+#define ETH_RXBUFNB 3 or 4
+#define ETH_TXBUFNB 2 or 3
+#define ETH_RX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
+#define ETH_TX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
+
+The best size for 'ETH_RXBUFNB' and 'ETH_TXBUFNB' depends on the speed of the CPU. These macro's define the number of DMA buffers for reception and for transmission.
+In general, if the CPU is very fast, you will need less buffers. You can obtain an estimate empirically.
+
+The optimal value of 'ETH_RX_BUF_SIZE' and 'ETH_TX_BUF_SIZE' depends on the actual value of 'ipconfigNETWORK_MTU'.
+When MTU is 1500, MTU+36 becomes a well-aligned buffer of 1536 bytes ( 0x600 ).
+When MTU is 1200, MTU+48 will make 1248 ( 0x4E0 ), which is also well aligned.
+
+Having well aligned buffers is important for CPU with memory cache. Often the caching system divides memory in blocks of 32 bytes. When two buffers share the same cache buffer, you are bound to see data errors.
+
+Without memory caching, let the size be at least a multiple of 8 ( for DMA ), and make it at least "ipconfigNETWORK_MTU + 14".
+
+STM32F7xx only:
+
+Networkinterface.c will place the 2 DMA tables in a special section called 'first_data'.
+In case 'BufferAllocation_1.c' is used, the network packets will also be declared in this section 'first_data'.
+As long as the part has no caching, this section can be placed anywhere in RAM.
+On an STM32F7 with an L1 data cache, it shall be placed in the first 64KB of RAM, which is always uncached.
+The linker script must be changed for this, for instance as follows:
+
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .; // create a global symbol at data start
++ *(.first_data) // .first_data sections
+ *(.data) // .data sections
+ *(.data*) // .data* sections
+
+ . = ALIGN(4);
+ _edata = .; // define a global symbol at data end
+ } >RAM AT> FLASH
+
+
+The driver contains these files:
+
+ stm32fxx_hal_eth.c
+ stm32f2xx_hal_eth.h
+ stm32f4xx_hal_eth.h
+ stm32f7xx_hal_eth.h
+ stm32fxx_hal_eth.h
+
+These files are copied from ST's HAL library. These work both for STM32F4 and STM32F7.
+Please remove or rename these files from the HAL distribution that you are using.
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
index 1c11976cb..4a6af81f9 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
@@ -1,27 +1,27 @@
/*
-FreeRTOS+TCP V2.0.11
-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 V202002.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
/* Standard includes. */
#include <stdint.h>
@@ -38,6 +38,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_ARP.h"
#include "NetworkBufferManagement.h"
#include "NetworkInterface.h"
@@ -50,10 +51,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Provided memory configured as uncached. */
#include "uncached_memory.h"
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004UL
+#ifndef niEMAC_HANDLER_TASK_PRIORITY
+ /* Define the priority of the task prvEMACHandlerTask(). */
+ #define niEMAC_HANDLER_TASK_PRIORITY configMAX_PRIORITIES - 1
#endif
+#define niBMSR_LINK_STATUS 0x0004uL
+
#ifndef PHY_LS_HIGH_CHECK_TIME_MS
/* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
receiving packets. */
@@ -83,6 +87,13 @@ FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
#define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
#endif
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 || ipconfigZERO_COPY_TX_DRIVER == 0 )
+ #error Please define both 'ipconfigZERO_COPY_RX_DRIVER' and 'ipconfigZERO_COPY_TX_DRIVER' as 1
+#endif
+
+#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 || ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ #warning Please define both 'ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM' and 'ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM' as 1
+#endif
/*-----------------------------------------------------------*/
/*
@@ -96,6 +107,10 @@ static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
*/
static void prvEMACHandlerTask( void *pvParameters );
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources( void );
+#endif
+
/*-----------------------------------------------------------*/
/* EMAC data/descriptions. */
@@ -119,7 +134,7 @@ XEmacPs_Config mac_config =
extern int phy_detected;
/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
+static uint32_t ulPHYLinkStatus = 0uL;
#if( ipconfigUSE_LLMNR == 1 )
static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
@@ -188,7 +203,7 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
possible priority to ensure the interrupt handler can return directly
to it. The task's handle is stored in xEMACTaskHandle so interrupts can
notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle );
}
else
{
@@ -206,7 +221,24 @@ const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pd
BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
{
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ ProtocolPacket_t *pxPacket;
+
+ /* If the peripheral must calculate the checksum, it wants
+ the protocol checksum to have a value of zero. */
+ pxPacket = ( ProtocolPacket_t * ) ( pxBuffer->pucEthernetBuffer );
+ if( ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_UDP ) &&
+ ( pxPacket->xICMPPacket.xIPHeader.ucProtocol != ipPROTOCOL_TCP ) )
+ {
+ /* The EMAC will calculate the checksum of the IP-header.
+ It can only calculate protocol checksums of UDP and TCP,
+ so for ICMP and other protocols it must be done manually. */
+ usGenerateProtocolChecksum( (uint8_t*)&( pxPacket->xUDPPacket ), pxBuffer->xDataLength, pdTRUE );
+ }
+ }
+ #endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
{
iptraceNETWORK_INTERFACE_TRANSMIT();
emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
@@ -249,7 +281,7 @@ BaseType_t xReturn;
}
ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
{
xReturn = pdTRUE;
break;
@@ -281,7 +313,7 @@ BaseType_t xGetPhyLinkStatus( void )
{
BaseType_t xReturn;
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )
{
xReturn = pdFALSE;
}
@@ -294,12 +326,58 @@ BaseType_t xReturn;
}
/*-----------------------------------------------------------*/
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources()
+ {
+ static UBaseType_t uxLastMinBufferCount = 0u;
+ static size_t uxMinLastSize = 0uL;
+ UBaseType_t uxCurrentBufferCount;
+ size_t uxMinSize;
+
+ uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
+
+ if( uxLastMinBufferCount != uxCurrentBufferCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentBufferCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(),
+ uxCurrentBufferCount ) );
+ }
+
+ uxMinSize = xPortGetMinimumEverFreeHeapSize();
+
+ if( uxMinLastSize != uxMinSize )
+ {
+ uxMinLastSize = uxMinSize;
+ FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
+ }
+
+ #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+ UBaseType_t uxCurrentCount = 0u;
+
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+ }
+#endif /* ( ipconfigHAS_PRINTF != 0 ) */
+/*-----------------------------------------------------------*/
+
static void prvEMACHandlerTask( void *pvParameters )
{
TimeOut_t xPhyTime;
TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
BaseType_t xResult = 0;
uint32_t xStatus;
const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
@@ -316,30 +394,11 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
for( ;; )
{
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
+ #if ( ipconfigHAS_PRINTF != 0 )
{
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ prvMonitorResources();
}
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+ #endif /* ipconfigHAS_PRINTF != 0 ) */
if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
{
@@ -372,19 +431,26 @@ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
vTaskSetTimeOutState( &xPhyTime );
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
xResult = 0;
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) == 0uL )
+ {
+ /* Indicate that the Link Status is high, so that
+ xNetworkInterfaceOutput() can send packets. */
+ ulPHYLinkStatus |= niBMSR_LINK_STATUS;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume 1\n" ) );
+ }
}
else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
{
xStatus = ulReadMDIO( PHY_REG_01_BMSR );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != ( xStatus & niBMSR_LINK_STATUS ) )
{
ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL ) );
}
vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ if( ( ulPHYLinkStatus & niBMSR_LINK_STATUS ) != 0uL )
{
xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
index f9e54bb2f..10a72b464 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
@@ -5,6 +5,7 @@ NetworkInterface for Xilinx' Zynq
Please include the following source files:
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/NetworkInterface.c
+ $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/uncached_memory.c
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
$(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
@@ -23,3 +24,14 @@ The following source files are NOT used for the FreeRTOS+TCP interface:
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_bdring.c
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_hw.c
$(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_sinit.c
+
+It is recommended to have these defined :
+
+#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
+#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
+#define ipconfigUSE_LINKED_RX_MESSAGES 1
+
+It is obligatory to define:
+
+#define ipconfigZERO_COPY_RX_DRIVER 1
+#define ipconfigZERO_COPY_TX_DRIVER 1
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
index b43e50ec2..bfbdc341b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
@@ -1,10 +1,35 @@
/*
+ * FreeRTOS V202002.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
+
+/*
* uncached_memory.c
*
* This module will declare 1 MB of memory and switch off the caching for it.
*
* pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
- * rounded up to a multiple of 4 KB
+ * rounded up to a multiple of 4 KB.
*
* ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT
* within the range of the 1 MB non-cached memory.
@@ -43,23 +68,35 @@
#include "uncached_memory.h"
-#define UNCACHED_MEMORY_SIZE 0x100000ul
+/* Reserve 1 MB of memory. */
+#define uncMEMORY_SIZE 0x100000uL
+
+/* Make sure that each pointer has an alignment of 4 KB. */
+#define uncALIGNMENT_SIZE 0x1000uL
#define DDR_MEMORY_END (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)
+#define uncMEMORY_ATTRIBUTE 0x1C02
+
static void vInitialiseUncachedMemory( void );
static uint8_t *pucHeadOfMemory;
static uint32_t ulMemorySize;
static uint8_t *pucStartOfMemory = NULL;
+/* The linker file defines some pseudo variables. '_end' is one of them.
+It is located at the first free byte in RAM. */
+extern u8 _end;
+
+/*-----------------------------------------------------------*/
+
uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )
{
uint8_t ucReturn;
if( ( pucStartOfMemory != NULL ) &&
( pucBuffer >= pucStartOfMemory ) &&
- ( pucBuffer < ( pucStartOfMemory + UNCACHED_MEMORY_SIZE ) ) )
+ ( pucBuffer < ( pucStartOfMemory + uncMEMORY_SIZE ) ) )
{
ucReturn = pdFALSE;
}
@@ -70,10 +107,12 @@ uint8_t ucReturn;
return ucReturn;
}
+/*-----------------------------------------------------------*/
uint8_t *pucGetUncachedMemory( uint32_t ulSize )
{
uint8_t *pucReturn;
+uint32_t ulSkipSize;
if( pucStartOfMemory == NULL )
{
@@ -85,48 +124,40 @@ uint8_t *pucReturn;
}
else
{
- uint32_t ulSkipSize;
-
pucReturn = pucHeadOfMemory;
- ulSkipSize = ( ulSize + 0x1000ul ) & ~0xffful;
+ /* Make sure that the next pointer return will have a good alignment. */
+ ulSkipSize = ( ulSize + uncALIGNMENT_SIZE ) & ~( uncALIGNMENT_SIZE - 1uL );
pucHeadOfMemory += ulSkipSize;
ulMemorySize -= ulSkipSize;
}
return pucReturn;
}
-
-extern u8 _end;
+/*-----------------------------------------------------------*/
static void vInitialiseUncachedMemory( )
{
/* At the end of program's space... */
- pucStartOfMemory = (uint8_t *) &_end;
- /*
- * Align the start address to 1 MB boundary.
- */
- pucStartOfMemory = (uint8_t *)( ( ( uint32_t )pucStartOfMemory + UNCACHED_MEMORY_SIZE ) & ( ~( UNCACHED_MEMORY_SIZE - 1 ) ) );
+ pucStartOfMemory = ( uint8_t * ) &( _end );
- if( ( ( u32 )pucStartOfMemory ) + UNCACHED_MEMORY_SIZE > DDR_MEMORY_END )
+ /* Align the start address to 1 MB boundary. */
+ pucStartOfMemory = ( uint8_t * )( ( ( uint32_t )pucStartOfMemory + uncMEMORY_SIZE ) & ( ~( uncMEMORY_SIZE - 1 ) ) );
+
+ if( ( ( u32 )pucStartOfMemory ) + uncMEMORY_SIZE > DDR_MEMORY_END )
{
-// vLoggingPrintf("vInitialiseUncachedMemory: Can not allocate uncached memory\n" );
+ FreeRTOS_printf( ( "vInitialiseUncachedMemory: Can not allocate uncached memory\n" ) );
}
else
{
- /*
- * Some objects want to be stored in uncached memory. Hence the 1 MB
- * address range that starts after "_end" is made uncached
- * by setting appropriate attributes in the translation table.
- */
- /* FIXME claudio rossi. Modified to prevent data abort exception (misaligned access)
- * when application is compiled with -O1 or more optimization flag.
- */
-/* Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0xc02 ); // addr, attr */
- Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0x1c02 ); // addr, attr
-
- /* For experiments in the SDIO driver, make the remaining uncached memory public */
+ /* Some objects want to be stored in uncached memory. Hence the 1 MB
+ address range that starts after "_end" is made uncached by setting
+ appropriate attributes in the translation table. */
+ Xil_SetTlbAttributes( ( uint32_t ) pucStartOfMemory, uncMEMORY_ATTRIBUTE );
+
+ /* For experiments in the SDIO driver, make the remaining uncached memory
+ public */
pucHeadOfMemory = pucStartOfMemory;
- ulMemorySize = UNCACHED_MEMORY_SIZE;
- memset( pucStartOfMemory, '\0', UNCACHED_MEMORY_SIZE );
+ ulMemorySize = uncMEMORY_SIZE;
+ memset( pucStartOfMemory, '\0', uncMEMORY_SIZE );
}
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
index 823dee0d3..bf0d174c0 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
@@ -26,7 +26,6 @@ extern "C" {
#include <stdint.h>
#include "xstatus.h"
-#include "sleep.h"
#include "xparameters.h"
#include "xparameters_ps.h" /* defines XPAR values */
#include "xil_types.h"
@@ -35,7 +34,6 @@ extern "C" {
#include "xil_exception.h"
#include "xpseudo_asm.h"
#include "xil_cache.h"
-#include "xil_printf.h"
#include "xuartps.h"
#include "xscugic.h"
#include "xemacps.h" /* defines XEmacPs API */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
index fc09d2183..913b4b46c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
@@ -1,36 +1,27 @@
/*
-FreeRTOS+TCP V2.0.11
-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
-*/
-
-#include "Zynq/x_emacpsif.h"
-#include "Zynq/x_topology.h"
-#include "xstatus.h"
-
-#include "xparameters.h"
-#include "xparameters_ps.h"
-#include "xil_exception.h"
-#include "xil_mmu.h"
+ * FreeRTOS V202002.00
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
#include "FreeRTOS.h"
#include "task.h"
@@ -43,6 +34,15 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
+#include "Zynq/x_emacpsif.h"
+#include "Zynq/x_topology.h"
+#include "xstatus.h"
+
+#include "xparameters.h"
+#include "xparameters_ps.h"
+#include "xil_exception.h"
+#include "xil_mmu.h"
+
#include "uncached_memory.h"
/* Two defines used to set or clear the EMAC interrupt */
@@ -56,7 +56,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#endif
#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
-#define RX_BUFFER_ALIGNMENT 14
+#define dmaRX_TX_BUFFER_SIZE 1536
/* Defined in NetworkInterface.c */
extern TaskHandle_t xEMACTaskHandle;
@@ -120,8 +120,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
{
break;
}
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-#warning ipconfigZERO_COPY_TX_DRIVER is defined
{
void *pvBuffer = pxDMA_tx_buffers[ tail ];
NetworkBufferDescriptor_t *pxBuffer;
@@ -140,7 +138,6 @@ size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount
}
}
}
-#endif
/* Clear all but the "used" and "wrap" bits. */
if( tail < ipconfigNIC_N_TX_DESC - 1 )
{
@@ -170,6 +167,11 @@ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xemacpsif = (xemacpsif_s *)(arg);
+ /* This function is called from an ISR. The Xilinx ISR-handler has already
+ cleared the TXCOMPL and TXSR_USEDREAD status bits in the XEMACPS_TXSR register.
+ But it forgets to do a read-back. Do so now to avoid ever-returning ISR's. */
+ ( void ) XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_TXSR_OFFSET);
+
/* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
"isr_events". The task in NetworkInterface will wake-up and do the necessary work.
*/
@@ -188,7 +190,7 @@ static BaseType_t xValidLength( BaseType_t xLength )
{
BaseType_t xReturn;
- if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
+ if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= dmaRX_TX_BUFFER_SIZE ) )
{
xReturn = pdTRUE;
}
@@ -207,12 +209,8 @@ int iHasSent = 0;
uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* This driver wants to own all network buffers which are to be transmitted. */
- configASSERT( iReleaseAfterSend != pdFALSE );
- }
- #endif
+ /* This driver wants to own all network buffers which are to be transmitted. */
+ configASSERT( iReleaseAfterSend != pdFALSE );
/* Open a do {} while ( 0 ) loop to be able to call break. */
do
@@ -235,7 +233,6 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
break;
}
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
/* Pass the pointer (and its ownership) directly to DMA. */
pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
@@ -244,15 +241,7 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
}
/* Buffer has been transferred, do not release it. */
iReleaseAfterSend = pdFALSE;
-#else
- if( pxDMA_tx_buffers[ head ] == NULL )
- {
- FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
- break;
- }
- /* Copy the message to unbuffered space in RAM. */
- memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
-#endif
+
/* Packets will be sent one-by-one, so for each packet
the TXBUF_LAST bit will be set. */
ulFlags |= XEMACPS_TXBUF_LAST_MASK;
@@ -292,6 +281,8 @@ TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
/* Start transmit */
xemacpsif->txBusy = pdTRUE;
XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
+ /* Read back the register to make sure the data is flushed. */
+ ( void ) XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET );
}
dsb();
@@ -306,6 +297,11 @@ void emacps_recv_handler(void *arg)
xemacpsif = (xemacpsif_s *)(arg);
xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
+ /* The driver has already cleared the FRAMERX, BUFFNA and error bits
+ in the XEMACPS_RXSR register,
+ But it forgets to do a read-back. Do so now. */
+ ( void ) XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXSR_OFFSET);
+
if( xEMACTaskHandle != NULL )
{
vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
@@ -314,33 +310,35 @@ void emacps_recv_handler(void *arg)
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
-static NetworkBufferDescriptor_t *ethMsg = NULL;
-static NetworkBufferDescriptor_t *ethLast = NULL;
-
-static void passEthMessages( void )
+static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
{
IPStackEvent_t xRxEvent;
xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) ethMsg;
+ xRxEvent.pvData = ( void * ) pxDescriptor;
if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
{
/* The buffer could not be sent to the stack so must be released again.
This is a deferred handler taskr, not a real interrupt, so it is ok to
use the task level function here. */
- do
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
- vReleaseNetworkBufferAndDescriptor( ethMsg );
- ethMsg = xNext;
- } while( ethMsg != NULL );
-
+ do
+ {
+ NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ pxDescriptor = pxNext;
+ } while( pxDescriptor != NULL );
+ }
+ #else
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
+ FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
}
-
- ethMsg = ethLast = NULL;
}
int emacps_check_rx( xemacpsif_s *xemacpsif )
@@ -349,6 +347,10 @@ NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
int rx_bytes;
volatile int msgCount = 0;
int head = xemacpsif->rxHead;
+#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
+ NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
+#endif /* ipconfigUSE_LINKED_RX_MESSAGES */
/* There seems to be an issue (SI# 692601), see comments below. */
resetrx_on_no_rxdata(xemacpsif);
@@ -364,12 +366,12 @@ int head = xemacpsif->rxHead;
break;
}
- pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ pxNewBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 );
if( pxNewBuffer == NULL )
{
/* A packet has been received, but there is no replacement for this Network Buffer.
The packet will be dropped, and it Network Buffer will stay in place. */
- FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
+ FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Network Buffer\n" ) );
pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
}
else
@@ -394,26 +396,35 @@ int head = xemacpsif->rxHead;
/* store it in the receive queue, where it'll be processed by a
different handler. */
iptraceNETWORK_INTERFACE_RECEIVE();
- pxBuffer->pxNextBuffer = NULL;
-
- if( ethMsg == NULL )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- // Becomes the first message
- ethMsg = pxBuffer;
+ pxBuffer->pxNextBuffer = NULL;
+
+ if( pxFirstDescriptor == NULL )
+ {
+ // Becomes the first message
+ pxFirstDescriptor = pxBuffer;
+ }
+ else if( pxLastDescriptor != NULL )
+ {
+ // Add to the tail
+ pxLastDescriptor->pxNextBuffer = pxBuffer;
+ }
+
+ pxLastDescriptor = pxBuffer;
}
- else if( ethLast != NULL )
+ #else
{
- // Add to the tail
- ethLast->pxNextBuffer = pxBuffer;
+ prvPassEthMessages( pxBuffer );
}
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- ethLast = pxBuffer;
msgCount++;
}
{
if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
{
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ Xil_DCacheInvalidateRange( ( ( uint32_t ) pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, ( uint32_t ) dmaRX_TX_BUFFER_SIZE );
}
{
uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
@@ -422,8 +433,10 @@ int head = xemacpsif->rxHead;
addr |= XEMACPS_RXBUF_WRAP_MASK;
}
/* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
- xemacpsif->rxSegments[ head ].address = addr;
xemacpsif->rxSegments[ head ].flags = 0;
+ xemacpsif->rxSegments[ head ].address = addr;
+ /* Make sure that the value has reached the peripheral by reading it back. */
+ ( void ) xemacpsif->rxSegments[ head ].address;
}
}
@@ -434,10 +447,14 @@ int head = xemacpsif->rxHead;
xemacpsif->rxHead = head;
}
- if( ethMsg != NULL )
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
{
- passEthMessages( );
+ if( pxFirstDescriptor != NULL )
+ {
+ prvPassEthMessages( pxFirstDescriptor );
+ }
}
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
return msgCount;
}
@@ -455,11 +472,7 @@ unsigned char *ucTxBuffer;
{
xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- pxDMA_tx_buffers[ index ] = ( void* )NULL;
-#else
- pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
-#endif
+ pxDMA_tx_buffers[ index ] = ( unsigned char * )NULL;
ucTxBuffer += xemacpsif->uTxUnitSize;
}
xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
@@ -479,8 +492,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
- /* Also round-up to 4KB */
- xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
+ xemacpsif->uTxUnitSize = dmaRX_TX_BUFFER_SIZE;
/*
* We allocate 65536 bytes for RX BDs which can accommodate a
* maximum of 8192 BDs which is much more than any application
@@ -507,7 +519,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
pxBuffer = pxDMA_rx_buffers[ iIndex ];
if( pxBuffer == NULL )
{
- pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ pxBuffer = pxGetNetworkBufferWithDescriptor( dmaRX_TX_BUFFER_SIZE, ( TickType_t ) 0 );
if( pxBuffer == NULL )
{
FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
@@ -523,7 +535,7 @@ XStatus init_dma(xemacpsif_s *xemacpsif)
if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
{
Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
- (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ (unsigned)dmaRX_TX_BUFFER_SIZE );
}
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
index e9443cda8..3d835d9a2 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
@@ -22,19 +22,19 @@
#include <stdio.h>
#include <stdlib.h>
-#include "Zynq/x_emacpsif.h"
-
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
-///* FreeRTOS+TCP includes. */
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "Zynq/x_emacpsif.h"
extern TaskHandle_t xEMACTaskHandle;
@@ -42,8 +42,6 @@ extern TaskHandle_t xEMACTaskHandle;
*** to run it on a PEEP board
***/
-unsigned int link_speed = 100;
-
void setup_isr( xemacpsif_s *xemacpsif )
{
/*
@@ -141,8 +139,6 @@ int xResult;
return xResult;
}
-BaseType_t xNetworkInterfaceInitialise( void );
-
static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
{
xemacpsif_s *xemacpsif;
@@ -218,8 +214,6 @@ static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
}
}
-extern XEmacPs_Config mac_config;
-
void HandleTxErrors(xemacpsif_s *xemacpsif)
{
u32 netctrlreg;
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
index 12b8c60c8..62228d065 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
@@ -53,24 +53,23 @@
#include <stdio.h>
#include <stdlib.h>
-#include "Zynq/x_emacpsif.h"
-//#include "lwipopts.h"
-#include "xparameters_ps.h"
-#include "xparameters.h"
-
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
-///* FreeRTOS+TCP includes. */
/* FreeRTOS+TCP includes. */
#include "FreeRTOS_IP.h"
#include "FreeRTOS_Sockets.h"
#include "FreeRTOS_IP_Private.h"
#include "NetworkBufferManagement.h"
+#include "Zynq/x_emacpsif.h"
+#include "xparameters_ps.h"
+#include "xparameters.h"
+
+
int phy_detected = 0;
/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
@@ -99,6 +98,8 @@ int phy_detected = 0;
#define IEEE_CONTROL_REG_OFFSET 0
#define IEEE_STATUS_REG_OFFSET 1
+#define IEEE_PHYSID1_OFFSET 2
+#define IEEE_PHYSID2_OFFSET 3
#define IEEE_AUTONEGO_ADVERTISE_REG 4
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
@@ -135,9 +136,6 @@ int phy_detected = 0;
#define IEEE_PAUSE_MASK 0x0400
#define IEEE_AUTONEG_ERROR_MASK 0x8000
-#define PHY_DETECT_REG 1
-#define PHY_DETECT_MASK 0x1808
-
#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
@@ -161,21 +159,24 @@ int phy_detected = 0;
#define EMAC0_BASE_ADDRESS 0xE000B000
#define EMAC1_BASE_ADDRESS 0xE000C000
+#define PHY_ADDRESS_COUNT 32
+
+#define MINIMUM_SLEEP_TIME 2
+
+
static int detect_phy(XEmacPs *xemacpsp)
{
- u16 phy_reg;
- u32 phy_addr;
-
- for (phy_addr = 31; phy_addr > 0; phy_addr--) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
- &phy_reg);
-
- if ((phy_reg != 0xFFFF) &&
- ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
- /* Found a valid PHY address */
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
- phy_addr));
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
+ u16 id_lower, id_upper;
+ u32 phy_addr, id;
+
+ for (phy_addr = 0; phy_addr < PHY_ADDRESS_COUNT; phy_addr++) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PHYSID1_OFFSET, &id_lower);
+
+ if ((id_lower != ( u16 )0xFFFFu) && (id_lower != ( u16 )0x0u)) {
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PHYSID2_OFFSET, &id_upper);
+ id = ( ( ( uint32_t ) id_upper ) << 16 ) | ( id_lower & 0xFFF0 );
+ FreeRTOS_printf( ("XEmacPs detect_phy: %04lX at address %d.\n", id, phy_addr ) );
phy_detected = phy_addr;
return phy_addr;
}
@@ -238,8 +239,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
return 10;
- xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__);
+ FreeRTOS_printf( ( "%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\n",
+ __FUNCTION__ ) );
return 10;
} else {
@@ -257,8 +258,8 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
case (IEEE_CTRL_LINKSPEED_10M):
return 10;
default:
- xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__, phylinkspeed);
+ FreeRTOS_printf( ( "%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\n",
+ __FUNCTION__, phylinkspeed ) );
return 10;
}
@@ -282,7 +283,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
#else
u32 phy_addr = detect_phy(xemacpsp);
#endif
- xil_printf("Start PHY autonegotiation \r\n");
+ FreeRTOS_printf( ( "Start PHY autonegotiation \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
@@ -338,24 +339,24 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
break;
}
#endif
- xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
+ FreeRTOS_printf( ( "Waiting for PHY to complete autonegotiation.\n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
&temp);
if (temp & IEEE_AUTONEG_ERROR_MASK) {
- xil_printf("Auto negotiation error \r\n");
+ FreeRTOS_printf( ( "Auto negotiation error \n" ) );
}
#endif
XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
&status);
}
- xil_printf("autonegotiation complete \r\n");
+ FreeRTOS_printf( ( "autonegotiation complete \n" ) );
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
#else
@@ -363,7 +364,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
#endif
#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
+ FreeRTOS_printf( ( "Waiting for Link to be up; Polling for SGMII core Reg \n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
while(!(temp & 0x8000)) {
XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
@@ -380,7 +381,7 @@ unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
return 10;
} else {
- xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
+ FreeRTOS_printf( ( "get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\n" ) );
XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
return 10;
@@ -560,26 +561,26 @@ unsigned Phy_Setup (XEmacPs *xemacpsp)
link_speed = 1000;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#elif defined(ipconfigNIC_LINKSPEED100)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
link_speed = 100;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#elif defined(ipconfigNIC_LINKSPEED10)
SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
link_speed = 10;
configure_IEEE_phy_speed(xemacpsp, link_speed);
convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
- sleep(1);
+ vTaskDelay( MINIMUM_SLEEP_TIME );
#endif
if (conv_present) {
XEmacPs_PhyWrite(xemacpsp, convphyaddr,
XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
}
- xil_printf("link speed: %d\r\n", link_speed);
+ FreeRTOS_printf( ( "link speed: %d\n", link_speed ) );
return link_speed;
}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
index 96503f457..040516361 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
@@ -44,6 +44,14 @@ enum if_state_t {
static const char *TAG = "NetInterface";
volatile static uint32_t xInterfaceState = INTERFACE_DOWN;
+/* protect the function declaration itself instead of using
+ #if everywhere. */
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvPrintResourceStats();
+#else
+ #define prvPrintResourceStats()
+#endif
+
BaseType_t xNetworkInterfaceInitialise( void )
{
static BaseType_t xMACAdrInitialized = pdFALSE;
@@ -78,6 +86,8 @@ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBu
}
}
+ prvPrintResourceStats();
+
if (xReleaseAfterSend == pdTRUE) {
vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
}
@@ -105,6 +115,8 @@ esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+ prvPrintResourceStats();
+
if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
ESP_LOGD(TAG, "Dropping packet");
esp_wifi_internal_free_rx_buffer(eb);
@@ -114,10 +126,10 @@ esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
if (pxNetworkBuffer != NULL) {
- /* Set the packet size, in case a larger buffer was returned. */
- pxNetworkBuffer->xDataLength = len;
+ /* Set the packet size, in case a larger buffer was returned. */
+ pxNetworkBuffer->xDataLength = len;
- /* Copy the packet data. */
+ /* Copy the packet data. */
memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
xRxEvent.pvData = (void *) pxNetworkBuffer;
@@ -133,3 +145,50 @@ esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
return ESP_FAIL;
}
}
+
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvPrintResourceStats()
+ {
+ static UBaseType_t uxLastMinBufferCount = 0u;
+ static UBaseType_t uxCurrentBufferCount = 0u;
+ static size_t uxMinLastSize = 0uL;
+ size_t uxMinSize;
+
+ uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
+
+ if( uxLastMinBufferCount != uxCurrentBufferCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentBufferCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
+ }
+
+ uxMinSize = xPortGetMinimumEverFreeHeapSize();
+
+ if( uxMinLastSize != uxMinSize )
+ {
+ uxMinLastSize = uxMinSize;
+ FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
+ }
+
+ #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+ UBaseType_t uxCurrentCount = 0u;
+
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+ }
+#endif /* ( ipconfigHAS_PRINTF != 0 ) */
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_declare.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_declare.h
new file mode 100644
index 000000000..8a10d5e7d
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_declare.h
@@ -0,0 +1,38 @@
+/*
+ * FreeRTOS+TCP V2.2.1
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
+
+#ifndef _AWS_FREERTOS_TCP_TEST_ACCESS_DECLARE_H_
+#define _AWS_FREERTOS_TCP_TEST_ACCESS_DECLARE_H_
+
+uint32_t TEST_FreeRTOS_TCP_prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
+ size_t xBufferLength,
+ TickType_t xIdentifier );
+
+void TEST_FreeRTOS_TCP_prvCheckOptions( FreeRTOS_Socket_t * pxSocket,
+ NetworkBufferDescriptor_t * pxNetworkBuffer );
+
+void TEST_FreeRTOS_TCP_prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket );
+
+#endif /* ifndef _AWS_FREERTOS_TCP_TEST_ACCESS_DECLARE_H_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_dns_define.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_dns_define.h
new file mode 100644
index 000000000..b9ee51c4b
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_dns_define.h
@@ -0,0 +1,48 @@
+/*
+ * FreeRTOS+TCP V2.2.1
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
+
+/**
+ * @file aws_ota_pal_test_access_define.h
+ * @brief Function wrappers that access private methods in aws_ota_pal.c.
+ *
+ * Needed for testing private functions.
+ */
+
+#ifndef _AWS_FREERTOS_TCP_TEST_ACCESS_DNS_DEFINE_H_
+#define _AWS_FREERTOS_TCP_TEST_ACCESS_DNS_DEFINE_H_
+
+#include "iot_freertos_tcp_test_access_declare.h"
+
+/*-----------------------------------------------------------*/
+
+uint32_t TEST_FreeRTOS_TCP_prvParseDNSReply( uint8_t * pucUDPPayloadBuffer,
+ size_t xBufferLength,
+ TickType_t xIdentifier )
+{
+ return prvParseDNSReply( pucUDPPayloadBuffer, xBufferLength, xIdentifier );
+}
+/*-----------------------------------------------------------*/
+
+#endif /* ifndef _AWS_FREERTOS_TCP_TEST_ACCESS_DNS_DEFINE_H_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_tcp_define.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_tcp_define.h
new file mode 100644
index 000000000..45e18e929
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_freertos_tcp_test_access_tcp_define.h
@@ -0,0 +1,53 @@
+/*
+ * FreeRTOS+TCP V2.2.1
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
+
+/**
+ * @file aws_ota_pal_test_access_define.h
+ * @brief Function wrappers that access private methods in aws_ota_pal.c.
+ *
+ * Needed for testing private functions.
+ */
+
+#ifndef _AWS_FREERTOS_TCP_TEST_ACCESS_TCP_DEFINE_H_
+#define _AWS_FREERTOS_TCP_TEST_ACCESS_TCP_DEFINE_H_
+
+#include "iot_freertos_tcp_test_access_declare.h"
+
+/*-----------------------------------------------------------*/
+
+void TEST_FreeRTOS_TCP_prvCheckOptions( FreeRTOS_Socket_t * pxSocket,
+ NetworkBufferDescriptor_t * pxNetworkBuffer )
+{
+ prvCheckOptions( pxSocket, pxNetworkBuffer );
+}
+/*-----------------------------------------------------------*/
+
+void TEST_FreeRTOS_TCP_prvTCPCreateWindow( FreeRTOS_Socket_t * pxSocket )
+{
+ prvTCPCreateWindow( pxSocket );
+}
+/*-----------------------------------------------------------*/
+
+#endif /* ifndef _AWS_FREERTOS_TCP_TEST_ACCESS_TCP_DEFINE_H_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_test_freertos_tcp.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_test_freertos_tcp.c
new file mode 100644
index 000000000..99b1d695b
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/test/iot_test_freertos_tcp.c
@@ -0,0 +1,362 @@
+/*
+ * FreeRTOS+TCP V2.2.1
+ * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION 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
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_DNS.h"
+
+/* Test includes. */
+#include "unity_fixture.h"
+#include "unity.h"
+#include "iot_freertos_tcp_test_access_declare.h"
+
+/**
+ * @brief Configuration for this test group.
+ */
+
+/*
+ * @brief Test group definition.
+ */
+TEST_GROUP( Full_FREERTOS_TCP );
+
+TEST_SETUP( Full_FREERTOS_TCP )
+{
+}
+
+TEST_TEAR_DOWN( Full_FREERTOS_TCP )
+{
+}
+
+TEST_GROUP_RUNNER( Full_FREERTOS_TCP )
+{
+ /* Run a parser test. */
+ RUN_TEST_CASE( Full_FREERTOS_TCP, prvParseDnsResponse );
+ RUN_TEST_CASE( Full_FREERTOS_TCP, ulDNSHandlePacket );
+
+ /* prvCheckOptions test. */
+ RUN_TEST_CASE( Full_FREERTOS_TCP, prvCheckOptions );
+
+ /* xProcessReceivedUDPPacket test. */
+ RUN_TEST_CASE( Full_FREERTOS_TCP, UDPPacketLength );
+}
+
+TEST( Full_FREERTOS_TCP, prvParseDnsResponse )
+{
+ uint8_t ucGoodDnsResponse[] =
+ {
+ 0xd7, 0x66, 0x81, 0x80, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x61, 0x33, 0x37,
+ 0x62, 0x78, 0x76, 0x31, 0x63, 0x62, 0x64, 0x61, 0x33, 0x6a, 0x67, 0x03, 0x69, 0x6f, 0x74, 0x09,
+ 0x75, 0x73, 0x2d, 0x77, 0x65, 0x73, 0x74, 0x2d, 0x32, 0x09, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e,
+ 0x61, 0x77, 0x73, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x05,
+ 0x00, 0x01, 0x00, 0x00, 0x01, 0x2c, 0x00, 0x1e, 0x0c, 0x69, 0x6f, 0x74, 0x6d, 0x6f, 0x6f, 0x6e,
+ 0x72, 0x61, 0x6b, 0x65, 0x72, 0x09, 0x75, 0x73, 0x2d, 0x77, 0x65, 0x73, 0x74, 0x2d, 0x32, 0x04,
+ 0x70, 0x72, 0x6f, 0x64, 0xc0, 0x1b, 0xc0, 0x48, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0xec,
+ 0x00, 0x45, 0x09, 0x64, 0x75, 0x61, 0x6c, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2a, 0x69, 0x6f, 0x74,
+ 0x6d, 0x6f, 0x6f, 0x6e, 0x72, 0x61, 0x6b, 0x65, 0x72, 0x2d, 0x75, 0x2d, 0x65, 0x6c, 0x62, 0x2d,
+ 0x31, 0x77, 0x38, 0x71, 0x6e, 0x77, 0x31, 0x33, 0x33, 0x36, 0x7a, 0x71, 0x2d, 0x31, 0x31, 0x38,
+ 0x36, 0x33, 0x34, 0x38, 0x30, 0x39, 0x32, 0x09, 0x75, 0x73, 0x2d, 0x77, 0x65, 0x73, 0x74, 0x2d,
+ 0x32, 0x03, 0x65, 0x6c, 0x62, 0xc0, 0x29, 0xc0, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x23, 0x00, 0x04, 0x22, 0xd3, 0x41, 0xdb, 0xc0, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x23, 0x00, 0x04, 0x22, 0xd3, 0x53, 0xe4, 0xc0, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x23, 0x00, 0x04, 0x22, 0xd3, 0xb6, 0x17, 0xc0, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x23, 0x00, 0x04, 0x22, 0xd6, 0xf5, 0xf0, 0xc0, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x23, 0x00, 0x04, 0x22, 0xd7, 0xe6, 0xa4, 0xc0, 0x72, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x23, 0x00, 0x04, 0x36, 0x95, 0x5e, 0x45
+ };
+ const uint32_t ulExpectedAddress = 0xdb41d322;
+ uint8_t ucBadDnsResponseA[] =
+ {
+ 0x3b, 0x6a, 0x81, 0x83, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x69, 0x6e, 0x73,
+ 0x70, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x08, 0x75, 0x73, 0x2d, 0x77, 0x65, 0x73, 0x74, 0x32, 0x09,
+ 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x61, 0x77, 0x73, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01,
+ 0x00, 0x01, 0xc0, 0x1f, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x33, 0x0e, 0x64,
+ 0x6e, 0x73, 0x2d, 0x64, 0x79, 0x6e, 0x2d
+ };
+ uint8_t ucBadDnsResponseB[] =
+ {
+ 0xf0, 0x23, 0x81, 0x80, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
+ 0x05, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
+ 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x7c, 0x00, 0x1b, 0x03, 0x77, 0x77, 0x77, 0x05,
+ 0x61, 0x70, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x07, 0x65, 0x64, 0x67, 0x65, 0x6b, 0x65,
+ 0x79, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2b, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x1a, 0xd5,
+ 0x00, 0x2f, 0x03, 0x77, 0x77, 0x77, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
+ 0x07, 0x65, 0x64, 0x67, 0x65, 0x6b, 0x65, 0x79, 0x03, 0x6e, 0x65, 0x74, 0x0b, 0x67, 0x6c, 0x6f,
+ 0x62, 0x61, 0x6c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x06, 0x61, 0x6b, 0x61, 0x64, 0x6e, 0x73, 0xc0,
+ 0x41, 0xc0, 0x52, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x08, 0xb3, 0x00, 0x19, 0x05, 0x65, 0x36,
+ 0x38, 0x35, 0x38, 0x05, 0x64, 0x73, 0x63, 0x65, 0x39, 0x0a, 0x61, 0x6b, 0x61, 0x6d, 0x61, 0x69,
+ 0x65, 0x64, 0x67, 0x65, 0xc0, 0x41, 0xc0, 0x8d, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a,
+ 0x00, 0x04, 0x17, 0x4a, 0x3e, 0x96
+ };
+ uint8_t ucBadDnsResponseC[] =
+ {
+ 0x3b, 0xa3, 0x81, 0x80, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
+ 0x09, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66
+ };
+ uint8_t ucBadDnsResponseD[] =
+ {
+ 0x95, 0x1e, 0x81, 0x80, 0x05, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
+ 0x03, 0x63, 0x6e, 0x6e, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00,
+ 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x1b, 0x0a, 0x74, 0x75, 0x72, 0x6e, 0x65, 0x72,
+ 0x2d, 0x74, 0x6c, 0x73, 0x03, 0x6d, 0x61, 0x70, 0x06, 0x66, 0x61, 0x73, 0x74, 0x6c, 0x79, 0x03,
+ 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x29, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04,
+ 0x97, 0x65, 0x35, 0x43
+ };
+ uint8_t ucBadDnsResponseE[] =
+ {
+ 0xa8, 0x6d, 0x81, 0x80, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
+ 0x05, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0,
+ 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x77, 0x77, 0x77, 0x05,
+ 0x61, 0x70, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x07, 0x65, 0x64, 0x67, 0x65, 0x6b, 0x65,
+ 0x79, 0x03, 0x6e, 0x65, 0x74, 0x00, 0xc0, 0x2b, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x1c, 0x2c,
+ 0x00, 0x2f, 0x03, 0x77, 0x77, 0x77, 0x05, 0x61, 0x70, 0x70, 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d,
+ 0x07, 0x65, 0x64, 0x67, 0x65, 0x6b, 0x65, 0x79, 0x03, 0x6e, 0x65, 0x74, 0x0b, 0x67, 0x6c, 0x6f,
+ 0x62, 0x61, 0x6c, 0x72, 0x65, 0x64, 0x69, 0x72, 0x06, 0x61, 0x6b, 0x61, 0x64, 0x6e, 0x73, 0xc0,
+ 0x41, 0xc0, 0x52, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x03, 0xd7, 0x00, 0x19, 0x05, 0x65, 0x36,
+ 0x38, 0x35, 0x38, 0x05, 0x64, 0x73, 0x63, 0x65, 0x39, 0x0a, 0x61, 0x6b, 0x61, 0x6d, 0x61, 0x69,
+ 0x65, 0x64, 0x67, 0x65, 0xc0, 0x41, 0xc0, 0x8d, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08,
+ 0x00, 0x04, 0x17, 0x4b, 0xba, 0x13
+ };
+ uint8_t ucBadDnsResponseF[] =
+ {
+ 0x6c, 0x1e, 0x81, 0x80, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
+ 0x06, 0x61, 0x6d, 0x61, 0x7a, 0x6f, 0x6e, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01,
+ 0xc0, 0x0c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x01, 0x57, 0x00, 0x0a, 0x03, 0x77, 0x77, 0x77,
+ 0x03, 0x63, 0x64, 0x6e, 0xc0, 0x10, 0x41, 0x41, 0xc0, 0x2c, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00,
+ 0x00, 0x17, 0x00, 0x1f, 0x0e, 0x64, 0x33, 0x61, 0x67, 0x34, 0x68, 0x75, 0x6b, 0x6b, 0x68, 0x36,
+ 0x32, 0x79, 0x6e, 0x0a, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x66, 0x72, 0x6f, 0x6e, 0x74, 0x03, 0x6e,
+ 0x65, 0x74, 0x00, 0xc0, 0x42, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x04, 0x0d,
+ 0x20, 0xa7, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x9a, 0x3a, 0x01, 0x5c, 0x31, 0x1f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+ };
+ uint8_t ucBadDnsResponseG[] =
+ {
+ 0x73, 0xe1, 0x81, 0x80, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x77, 0x77, 0x77,
+ 0x06, 0x22, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01, 0xc0, 0x0c, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x04, 0xd8, 0x3a, 0xd8, 0x84, 0x00, 0x34, 0x02, 0x41, 0x01,
+ 0x2c, 0xb2, 0x1a, 0x01, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+ };
+ uint8_t ucBadDnsResponseH[] = /* Regress crash in prvReadNameField. */
+ {
+ 0x10, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x35,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
+ 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ uint8_t ucBadDnsResponseI[] = /* Regress crash in prvSkipNameField. */
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
+ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
+ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x35,
+ 0x0a, 0xf8, 0xf8, 0xf8, 0x27, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
+ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x16, 0x16, 0x21, 0x16,
+ 0x16, 0x16, 0x16, 0x16, 0x16, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8,
+ 0x27, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x16, 0x16, 0x16, 0x16, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x16, 0x5a,
+ 0x00, 0x16, 0x00, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x21
+ };
+ uint32_t ulAddress = 0;
+
+ /* Parsing a valid packet should succeed. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucGoodDnsResponse,
+ sizeof( ucGoodDnsResponse ),
+ *( uint16_t * ) ucGoodDnsResponse );
+ TEST_ASSERT_EQUAL_UINT32( ulExpectedAddress, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseA,
+ sizeof( ucBadDnsResponseA ),
+ *( uint16_t * ) ucBadDnsResponseA );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseB,
+ sizeof( ucBadDnsResponseB ),
+ *( uint16_t * ) ucBadDnsResponseB );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseC,
+ sizeof( ucBadDnsResponseC ),
+ *( uint16_t * ) ucBadDnsResponseC );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseD,
+ sizeof( ucBadDnsResponseD ),
+ *( uint16_t * ) ucBadDnsResponseD );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseE,
+ sizeof( ucBadDnsResponseE ),
+ *( uint16_t * ) ucBadDnsResponseE );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseF,
+ sizeof( ucBadDnsResponseF ),
+ *( uint16_t * ) ucBadDnsResponseF );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseG,
+ sizeof( ucBadDnsResponseG ),
+ *( uint16_t * ) ucBadDnsResponseG );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseH,
+ sizeof( ucBadDnsResponseH ),
+ *( uint16_t * ) ucBadDnsResponseH );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+
+ /* Parsing a bad packet should fail gracefully. */
+ ulAddress = TEST_FreeRTOS_TCP_prvParseDNSReply(
+ ucBadDnsResponseI,
+ sizeof( ucBadDnsResponseI ),
+ *( uint16_t * ) ucBadDnsResponseI );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulAddress );
+ /* End test. */
+}
+
+TEST( Full_FREERTOS_TCP, ulDNSHandlePacket )
+{
+ NetworkBufferDescriptor_t xNetworkBuffer = { 0 };
+ uint8_t ucPartialUdpPacket[ sizeof( ipSIZE_OF_UDP_HEADER ) - 1 ] = { 0xFF };
+ uint32_t ulResult = 0;
+
+ /* Attempting to parse a packet that's shorter than a UDP header should be
+ * a no-op. */
+ xNetworkBuffer.pucEthernetBuffer = ucPartialUdpPacket;
+ xNetworkBuffer.xDataLength = sizeof( ucPartialUdpPacket );
+ ulResult = ulDNSHandlePacket( &xNetworkBuffer );
+ TEST_ASSERT_EQUAL_UINT32( 0, ulResult );
+}
+
+TEST( Full_FREERTOS_TCP, prvCheckOptions )
+{
+ uint8_t ucDivideByZero[] =
+ {
+ 0x6f, 0xff, 0xff, 0xff, 0x0a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0x6f, 0x6f, 0x6d,
+ 0x6f, 0xff, 0xff, 0xff, 0x0a, 0xff, 0xff, 0xff, 0xff, 0xe5, 0x6f, 0x6f,
+ 0x6f, 0x6f, 0x6f, 0x6b, 0xbf, 0x6f, 0x03, 0xff, 0x04, 0x01, 0xb7, 0xff,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0xf8, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05
+ };
+
+ FreeRTOS_Socket_t xSocket;
+ NetworkBufferDescriptor_t xNetworkBuffer;
+
+ xNetworkBuffer.pucEthernetBuffer = ucDivideByZero;
+ xNetworkBuffer.xDataLength = sizeof( ucDivideByZero );
+
+ TEST_FreeRTOS_TCP_prvTCPCreateWindow( &xSocket );
+ TEST_FreeRTOS_TCP_prvCheckOptions( &xSocket, &xNetworkBuffer );
+}
+
+TEST( Full_FREERTOS_TCP, UDPPacketLength )
+{
+ uint8_t ucBadUdpPacketA[] =
+ {
+ 0xff, 0xff
+ };
+
+ uint8_t ucBadUdpPacketB[] =
+ {
+ 0x0a, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0x54, 0xbf, 0xbf, 0xbf, 0xff, 0xbf,
+ 0x0a, 0xbf, 0xbf, 0xbf, 0x3f, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
+ 0x88, 0x00, 0xbf, 0xbf, 0xbf, 0x00, 0x32, 0xbf, 0xbf, 0xbf, 0x00, 0x35,
+ 0x0a, 0xbf, 0xbf, 0x3a, 0xbf, 0xbf, 0xbf
+ };
+
+ BaseType_t xReturn = pdPASS;
+ uint16_t usPort = 65535;
+ NetworkBufferDescriptor_t xNetworkBuffer;
+
+ 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 );
+ xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort );
+ TEST_ASSERT_EQUAL_UINT32_MESSAGE( pdFAIL, xReturn, "Failed to parse 2 bytes packet" );
+
+ xNetworkBuffer.pucEthernetBuffer = ucBadUdpPacketB;
+ xNetworkBuffer.xDataLength = sizeof( ucBadUdpPacketB );
+ xReturn = xProcessReceivedUDPPacket( &xNetworkBuffer, usPort );
+ TEST_ASSERT_EQUAL_UINT32( pdFAIL, xReturn );
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/uncrustify.cfg b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/uncrustify.cfg
new file mode 100644
index 000000000..31cd4b687
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/uncrustify.cfg
@@ -0,0 +1,164 @@
+# Uncrustify-0.67
+input_tab_size = 4 # unsigned number
+output_tab_size = 4 # unsigned number
+sp_arith = force # ignore/add/remove/force
+sp_assign = force # ignore/add/remove/force
+sp_assign_default = force # ignore/add/remove/force
+sp_before_assign = force # ignore/add/remove/force
+sp_after_assign = force # ignore/add/remove/force
+sp_enum_assign = force # ignore/add/remove/force
+sp_enum_before_assign = force # ignore/add/remove/force
+sp_enum_after_assign = force # ignore/add/remove/force
+sp_pp_stringify = add # ignore/add/remove/force
+sp_bool = force # ignore/add/remove/force
+sp_compare = force # ignore/add/remove/force
+sp_inside_paren = force # ignore/add/remove/force
+sp_paren_paren = force # ignore/add/remove/force
+sp_paren_brace = force # ignore/add/remove/force
+sp_before_ptr_star = force # ignore/add/remove/force
+sp_before_unnamed_ptr_star = force # ignore/add/remove/force
+sp_between_ptr_star = remove # ignore/add/remove/force
+sp_after_ptr_star = ignore # ignore/add/remove/force
+sp_before_byref = force # ignore/add/remove/force
+sp_after_byref = remove # ignore/add/remove/force
+sp_after_byref_func = remove # ignore/add/remove/force
+sp_before_angle = remove # ignore/add/remove/force
+sp_inside_angle = remove # ignore/add/remove/force
+sp_after_angle = force # ignore/add/remove/force
+sp_before_sparen = remove # ignore/add/remove/force
+sp_inside_sparen = force # ignore/add/remove/force
+sp_after_sparen = force # ignore/add/remove/force
+sp_sparen_brace = force # ignore/add/remove/force
+sp_before_semi_for = remove # ignore/add/remove/force
+sp_before_semi_for_empty = add # ignore/add/remove/force
+sp_after_semi_for_empty = force # ignore/add/remove/force
+sp_before_square = remove # ignore/add/remove/force
+sp_before_squares = remove # ignore/add/remove/force
+sp_inside_square = force # ignore/add/remove/force
+sp_after_comma = force # ignore/add/remove/force
+sp_after_cast = force # ignore/add/remove/force
+sp_inside_paren_cast = force # ignore/add/remove/force
+sp_sizeof_paren = remove # ignore/add/remove/force
+sp_inside_braces_enum = force # ignore/add/remove/force
+sp_inside_braces_struct = force # ignore/add/remove/force
+sp_inside_braces = force # ignore/add/remove/force
+sp_inside_braces_empty = remove # ignore/add/remove/force
+sp_type_func = force # ignore/add/remove/force
+sp_func_proto_paren = remove # ignore/add/remove/force
+sp_func_def_paren = remove # ignore/add/remove/force
+sp_inside_fparens = remove # ignore/add/remove/force
+sp_inside_fparen = force # ignore/add/remove/force
+sp_fparen_brace = add # ignore/add/remove/force
+sp_func_call_paren = remove # ignore/add/remove/force
+sp_func_class_paren = remove # ignore/add/remove/force
+sp_return_paren = remove # ignore/add/remove/force
+sp_attribute_paren = remove # ignore/add/remove/force
+sp_defined_paren = remove # ignore/add/remove/force
+sp_macro = force # ignore/add/remove/force
+sp_macro_func = force # ignore/add/remove/force
+sp_brace_typedef = force # ignore/add/remove/force
+sp_before_dc = remove # ignore/add/remove/force
+sp_after_dc = remove # ignore/add/remove/force
+sp_cond_colon = force # ignore/add/remove/force
+sp_cond_question = force # ignore/add/remove/force
+sp_case_label = force # ignore/add/remove/force
+sp_endif_cmt = force # ignore/add/remove/force
+sp_before_tr_emb_cmt = force # ignore/add/remove/force
+sp_num_before_tr_emb_cmt = 1 # unsigned number
+indent_columns = 4 # unsigned number
+indent_with_tabs = 2 # unsigned number
+indent_align_string = true # false/true
+indent_class = true # false/true
+indent_class_colon = true # false/true
+indent_member = 3 # unsigned number
+indent_switch_case = 4 # unsigned number
+indent_case_brace = 3 # number
+indent_var_def_blk = -4 # number
+nl_assign_leave_one_liners = true # false/true
+nl_class_leave_one_liners = true # false/true
+nl_start_of_file = remove # ignore/add/remove/force
+nl_end_of_file = force # ignore/add/remove/force
+nl_end_of_file_min = 1 # unsigned number
+nl_assign_brace = add # ignore/add/remove/force
+nl_func_var_def_blk = 1 # unsigned number
+nl_fcall_brace = add # ignore/add/remove/force
+nl_enum_brace = force # ignore/add/remove/force
+nl_struct_brace = force # ignore/add/remove/force
+nl_union_brace = force # ignore/add/remove/force
+nl_if_brace = add # ignore/add/remove/force
+nl_brace_else = add # ignore/add/remove/force
+nl_else_brace = add # ignore/add/remove/force
+nl_getset_brace = force # ignore/add/remove/force
+nl_for_brace = add # ignore/add/remove/force
+nl_while_brace = add # ignore/add/remove/force
+nl_do_brace = add # ignore/add/remove/force
+nl_switch_brace = add # ignore/add/remove/force
+nl_multi_line_define = true # false/true
+nl_before_case = true # false/true
+nl_after_case = true # false/true
+nl_func_type_name = remove # ignore/add/remove/force
+nl_func_proto_type_name = remove # ignore/add/remove/force
+nl_func_paren = remove # ignore/add/remove/force
+nl_func_def_paren = remove # ignore/add/remove/force
+nl_func_decl_start = remove # ignore/add/remove/force
+nl_func_def_start = remove # ignore/add/remove/force
+nl_func_decl_args = add # ignore/add/remove/force
+nl_func_def_args = add # ignore/add/remove/force
+nl_func_decl_end = remove # ignore/add/remove/force
+nl_func_def_end = remove # ignore/add/remove/force
+nl_fdef_brace = add # ignore/add/remove/force
+nl_after_semicolon = true # false/true
+nl_after_brace_open = true # false/true
+nl_after_brace_close = true # false/true
+nl_squeeze_ifdef = true # false/true
+nl_before_if = force # ignore/add/remove/force
+nl_after_if = force # ignore/add/remove/force
+nl_before_for = force # ignore/add/remove/force
+nl_after_for = force # ignore/add/remove/force
+nl_before_while = force # ignore/add/remove/force
+nl_after_while = force # ignore/add/remove/force
+nl_before_switch = force # ignore/add/remove/force
+nl_after_switch = force # ignore/add/remove/force
+nl_before_do = force # ignore/add/remove/force
+nl_after_do = force # ignore/add/remove/force
+nl_max = 4 # unsigned number
+nl_after_func_proto_group = 1 # unsigned number
+nl_after_func_body_class = 2 # unsigned number
+nl_before_block_comment = 2 # unsigned number
+eat_blanks_after_open_brace = true # false/true
+eat_blanks_before_close_brace = true # false/true
+nl_after_return = true # false/true
+pos_bool = trail # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force
+align_var_def_amp_style = 1 # unsigned number
+align_var_def_thresh = 16 # unsigned number
+align_assign_thresh = 12 # unsigned number
+align_struct_init_span = 3 # unsigned number
+align_typedef_gap = 3 # unsigned number
+align_typedef_span = 5 # unsigned number
+align_typedef_star_style = 1 # unsigned number
+align_typedef_amp_style = 1 # unsigned number
+align_right_cmt_span = 3 # unsigned number
+align_nl_cont = true # false/true
+align_pp_define_gap = 4 # unsigned number
+align_pp_define_span = 3 # unsigned number
+cmt_cpp_to_c = true # false/true
+cmt_star_cont = false # false/true
+cmt_indent_multi = false # false/true
+mod_full_brace_do = add # ignore/add/remove/force
+mod_full_brace_for = add # ignore/add/remove/force
+mod_full_brace_if = add # ignore/add/remove/force
+mod_full_brace_while = add # ignore/add/remove/force
+mod_full_paren_if_bool = true # false/true
+mod_remove_extra_semicolon = true # false/true
+mod_add_long_ifdef_endif_comment = 10 # unsigned number
+mod_add_long_ifdef_else_comment = 10 # unsigned number
+mod_case_brace = remove # ignore/add/remove/force
+mod_remove_empty_return = true # false/true
+pp_indent = force # ignore/add/remove/force
+pp_indent_at_level = true # false/true
+pp_indent_count = 4 # unsigned number
+pp_space = remove # ignore/add/remove/force
+pp_if_indent_code = true # false/true
+pp_indent_brace = false # false/true
+align_with_tabs = true # false/true
+# option(s) with 'not default' value: 162