This tutorial is about how to create a lwIP project with FreeRTOS using the Kinetis SDK V1.3.0 with Kinetis Design Studio on the Freescale FRDM-K64F board.
I would like to thank Frank Bargstedt for providing me the many hints and steps for this tutorial. Without his contribution I think I would not have been able to create this article. THANK YOU!
Introduction
lwIP is a small Open Source TCP/IP implementation suitable for small systems. The project can be found on http://savannah.nongnu.org/projects/lwip/. The Kinetis SDK comes with an lwIP port which I’m going to use in this project. The goal is to create a project with lwIP and FreeRTOS running on the FRDM-K64F board.
Preconditions
For this project I assume you have the following available/installed (see links at the end of this article):
- Freescale Kinetis Design Studio (KDS) V3.0.0. Alternatively stock Eclipse with Processor Expert installed (see “Going to Mars: Building a DIY Eclipse IDE for ARM Embedded Microcontrollers“) can be used.
- Freescale Kinetis SDK (KSDK) V1.3.0 and Kinetis SDK Eclipse update installed in Eclipse/KDS
- McuOnEclipse components Components 2015-10-17.zip or later
- FRDM-K64F board with cables, connected to a router with DHCP
Project Creation
In KDS, use the menu File > New > Kinetis Project to create a new project.
Provide a name for the project:
Select the board:
Select the Kinetis SDK with Processor Expert enabled:
Then finish, and the proejct is created.
Pin Settings
The next step is to check the pin muxing and pin settings:
By default the ENET pins are not routed:
In a first step have all pins routed:
Next we have to configure the RMII0_MDIO pin: for this we use the context menu on that pin and select ‘Pin Functional Properties’:
Configure the pin for slow slew rate, enabled open drain, low drive strength, disabled passive filter, pull-up selection with enabled pull-up as below:
❗ Important: without the above settings the ENET will not properly work!
fsl_enet Component
Next, add the fsl_enet SDK component from the Components Library to the project:
This adds the component to the project. It’s settings can be at the default settings.
Clock Configuration
In this section the clock gets configured. It is important that the clock is in sync with the PHY clock which runs at 50 MHZ. The settings I need to check are in the Clock Manager:
By default, the project has multiple clock configurations (which are a waste of code and RAM!):
Clicking into the line and using the ‘-‘ icon I can remove the configurations:
I reduce it to only one and set it as the Init clock Configuration:
That configuration I set to maximum clock speed with the 50 MHz clock source:
- Clock source: External Reference Clock with 50 MHz from EXTAL0
- MGG Mode set to PEE
- PLL output set to 120 MHz
- Core Clock set to 120 MHz
- Bus Clock set to 60 MHz
- External Bus Clock set to 40 MHz
- Flash Clock set to 24 MHz
fsl_os_abstraction
The default OS abstraction in the Kinetis SDK v1.3.0 comes with unnecessary overhead, so it needs some configuration:
I disable the OS Timers for bare metal mode as they are not needed:
FreeRTOS
Next, FreeRTOS gets added. I’m *not* using the FreeRTOS component which comes with the Kinetis SDK V1.3.0 as it is an older version and does not support advanced features like RTT Tracing (see “ Search Using Segger Real Time Terminal (RTT) with Eclipse“).
So I’m using the McuOnEclipse FreeRTOS component from the repository:
This adds FreeRTOS plus the Utility component to the project:
FreeRTOS gets configured as below:
- To prepare the RTOS to work with the Kinetis SDK, enable the SDK option and add the Kinetis SDK component to it:
- Verify the ARM CPU used, in the case of the FRDM-K64F it is an ARM Cortex-M4F with floating point support:
- As the rest of the SDK is using malloc()/free() too, I set the RTOS memory allocation to Scheme 3 too, with an appropriate Heap Size:
Enable Timers in the RTOS settings:
In the compiler preprocessor settings (menu Project > Properties) I need to tell the SDK that I’m using FreeRTOS with a define:
FSL_RTOS_FREE_RTOS
Generating Processor Expert Code
With all the components configured, I can generate Processor Expert code:
If this requires some file changes, a confirmation dialog might show up which I confirm with OK:
PHY Driver
The FRDM-K64F uses the ‘ksz8081’ PHY. To add the driver for it to my project I copy the following files
- fsl_phy_driver.c
- fsl_phy_driver.h
from
C:\Freescale\KSDK_1.3.0\middleware\tcpip\rtcs\source\port\phyksz8081
and add them to my project Sources folder:
Semihosting
I would like to use semihosting (see “Semihosting for Kinetis Design Studio V3.0.0 and GNU ARM Embedded (launchpad)“) to write messages to the debugger console instead of using a physical UART.
First, I add a file ‘fsl_debug_console.h’ to the sources:
which has defines to map debug printf calls to the normal printf:
/* * fsl_debug_console.h * * Map printf for semihosting implementation. */ #ifndef SOURCES_FSL_DEBUG_CONSOLE_H_ #define SOURCES_FSL_DEBUG_CONSOLE_H_ #define PRINTF printf #define debug_printf printf #endif /* SOURCES_FSL_DEBUG_CONSOLE_H_ */To tell the linker that I’m using semihosting, I use the following linker commands:
-specs=rdimon.specs -specs=nano.specsKinetis SDK Utilities
The Kinetis SDK utilities and internal printf routines do not play well with semihosting, so I had to disable it:
This can be easily done with using the context menu on that folder and exclude the resource from build:
lwIP
In this step the lwIP stack gets added to the project. There is a port of lwIP inside the Freescale Kinetis SDK V1.3.0 folder:
Copy the lwip folder into the project root folder:
I’m not going to use IPV6, so I delete the ipv6 folders, otherwise I will get compilation errors with both ipv6 and ipv4 active:
In order to the compiler to find all the header files, I’m adding the following include paths to the compiler settings:
"..\lwip\src\include" "..\lwip\src\include\lwip" "..\lwip\src\include\ipv4" "..\lwip\port"💡 I can copy-paste paths settings to the dialog in Eclipse.
Application Code
As application code I add this to main.c:
#define DHCP_TIMEOUT 10 #include "lwip/api.h" #include "lwip/tcpip.h" #include "lwip/udp.h" #include "lwip/dhcp.h" #include "netif/etharp.h" #include "ethernetif.h" #include <string.h> #include <stdio.h> /* providing a debug_printf() to make the linker happy */ int debug_printf(const char *fmt_s, ...) { #if 0 va_list ap; int result; /* Do nothing if the debug uart is not initialized.*/ if (s_debugConsole.type == kDebugConsoleNone) { return -1; } va_start(ap, fmt_s); result = _doprint(NULL, debug_putc, -1, (char *)fmt_s, ap); va_end(ap); return result; #else return -1; #endif } #if 1 /* depending on the GNU tools and libraries, a custom _sbrk() is needed */ void *_sbrk ( uint32_t delta ) { extern char end; /* Defined by the linker */ static char *heap_end; char *prev_heap_end; if (heap_end == 0) { heap_end = &end; } prev_heap_end = heap_end; heap_end += delta; return (void *) prev_heap_end; } #endif static void LwipInitTask(void* pvArguments) { err_t err; struct netif fsl_netif0; ip_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw; char msg[] = "This is my message"; (void)pvArguments; // Init lwip stack tcpip_init(NULL,NULL); printf("%s: lwip init called ..\n", __FUNCTION__); // Setup IP Config for DHCP ... IP4_ADDR(&fsl_netif0_ipaddr, 0,0,0,0); IP4_ADDR(&fsl_netif0_netmask, 0,0,0,0); IP4_ADDR(&fsl_netif0_gw, 0,0,0,0); /* Add a network interface to the list of lwIP netifs. */ netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, ethernetif_init, ethernet_input); /* Set the network interface as the default network interface. */ netif_set_default(&fsl_netif0); /* obtain the IP address, default gateway and subnet mask by using DHCP*/ err = dhcp_start(&fsl_netif0); printf("%s : Started DCHP request (%s)\n", __FUNCTION__, lwip_strerr(err)); for(int i=0; i < DHCP_TIMEOUT && fsl_netif0.dhcp->state != DHCP_BOUND; i++) { printf("%s : Current DHCP State : %d\n", __FUNCTION__, fsl_netif0.dhcp->state); // Wait a second vTaskDelay(1000/portTICK_PERIOD_MS); } // Make it active ... netif_set_up(&fsl_netif0); printf("%s : Interface is up : %d\n", __FUNCTION__, fsl_netif0.dhcp->state); printf("%s : IP %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.ip_addr)); printf("%s : NM %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.netmask)); printf("%s : GW %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.gw)); if (fsl_netif0.dhcp->state == DHCP_BOUND) { // Send out some UDP data struct netconn* pConnection; // Create UDP connection pConnection = netconn_new(NETCONN_UDP); // Connect to local port err = netconn_bind(pConnection, IP_ADDR_ANY, 12345); printf("%s : Bound to IP_ADDR_ANY port 12345 (%s)\n", __FUNCTION__, lwip_strerr(err)); err = netconn_connect(pConnection, IP_ADDR_BROADCAST, 12346 ); printf("%s : Connected to IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); for(int i = 0; i < 10; i++ ){ struct netbuf* buf = netbuf_new(); void* data = netbuf_alloc(buf, sizeof(msg)); memcpy (data, msg, sizeof (msg)); err = netconn_send(pConnection, buf); printf("%s : Sending to IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); netbuf_delete(buf); // De-allocate packet buffer // Wait a second vTaskDelay(1000/portTICK_PERIOD_MS); } err = netconn_disconnect(pConnection); printf("%s : Disconnected from IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); err = netconn_delete(pConnection); printf("%s : Deleted connection (%s)\n", __FUNCTION__, lwip_strerr(err)); } // Wait a second vTaskDelay(1000/portTICK_PERIOD_MS); /* finish the lease of the IP address */ err = dhcp_release(&fsl_netif0); printf("%s : DHCP Release (%s)\n", __FUNCTION__, lwip_strerr(err)); for(;;) {}; }And call it inside main() like below. An important point is that the MPU of the K64F needs to be disabled:
printf("Welcome to the world of lwip!\r\n"); /* Disable the mpu */ MPU_BWR_CESR_VLD(MPU, 0); /* create lwIP initialization task */ xTaskCreate(LwipInitTask, "LwipInitTask", configMINIMAL_STACK_SIZE * 4, (void*)NULL, tskIDLE_PRIORITY, (xTaskHandle*)NULL);After that, the RTOS gets started with vTaskStartScheduler().
Example Session
With this, I can build, download and debug the application. With the network cable plugged in, the application writes the status to the semihosting console. It starts with a DHCP request and then does some IP broadcasts and at the end releases the address and closes the connection:
Welcome to the world of lwip! LwipInitTask: lwip init called .. LwipInitTask : Started DCHP request (Ok.) LwipInitTask : Current DHCP State : 6 LwipInitTask : Current DHCP State : 6 LwipInitTask : Current DHCP State : 6 LwipInitTask : Current DHCP State : 8 LwipInitTask : Interface is up : 10 LwipInitTask : IP 192.168.0.123 LwipInitTask : NM 255.255.255.0 LwipInitTask : GW 192.168.0.1 LwipInitTask : Bound to IP_ADDR_ANY port 12345 (Ok.) LwipInitTask : Connected to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Sending to IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Disconnected from IP_ADDR_BROADCAST port 12346 (Ok.) LwipInitTask : Deleted connection (Ok.) LwipInitTask : DHCP Release (Ok.)Possible Problems
After publishing this article, there has been a problem report in the community (https://community.nxp.com/thread/381894). The problem is if the received frames are handled in an interrupt context and passed up the lwip stack. This causes problems with reentrance and can cause an assertion.
The solution is to set the following define to zero in <Kinetis SDK>\platform\drivers\inc\fsl_enet_driver.h
#ifndef ENET_RECEIVE_ALL_INTERRUPT #define ENET_RECEIVE_ALL_INTERRUPT 0 #endifSummary
A long-time-waiting thing on my to-do list finally has been accomplished: It takes many pieces to build the basis of a network IP application, and lwip for sure is a good and well documented open source project. With the help of Processor Expert many aspects of the networking application get simplified, and after some tweaks the Kinetis SDK is now working too.
The project created in this tutorial is on GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-K64F120M/FRDM-K64F_lwIP_FreeRTOS.
Happy Networking 🙂
Links
- lwip project: http://savannah.nongnu.org/projects/lwip/
- Freescale Kinetis Design Studio: http://www.freescale.com/kds
- Freescale Kinetis SDK: https://www.nxp.com
- Freescale FRDM-K64F board: http://www.freescale.com/products/arm-processors/kinetis-cortex-m/k-series/k6x-ethernet-mcus/freescale-freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F
- McuOnEclipse components: https://sourceforge.net/projects/mcuoneclipse/files/PEx%20Components/
- Project of this tutorial on GitHub: https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-K64F120M/FRDM-K64F_lwIP_FreeRTOS
Hi Erich,
did you do any benchmarks?
Best regards
Peter
LikeLike
Hi Peter,
no, I have not run any benchmarks yet.
Erich
LikeLike
Have you thought about doing an example with the official (or one day to be official) FreeRTOS TCP/IP stack? It’s currently listed on the FreeRTOS Labs page, along with a FAT filesystem.
http://www.freertos.org/FreeRTOS-Labs/index.shtml
LikeLike
Hi Brendan,
yes, I had thought about this, and would love to do this if time permits.
Erich
LikeLike
Hi
I have tried following your tutorial and i have downloaded your example from git but i always get stuck in mallocFailhook. I get stuck in LwipInitTask so the program is started. Does anyone have any idea in what could be wrong.
Thanks for a great tutorial.
Best regards
Andreas
LikeLike
Hi Andreas,
Did you change the FreeRTOS Memory Allocation Scheme to “Scheme 3” ? Normally this should take care of your problem.
Regards
Frank
LikeLike
Hi
Yes i have tried moste of the schemes including scheme 3, witch i started with. All of them gives me the same error.
Could it be some linker setting i have missed?
Best regards
Andreas
LikeLike
You need to make sure you have enough heap allocated. If you are using Heap3 (which you should use): make sure you have enough heap allocated in the linker file. Have you checked this?
LikeLike
As I wasn’t able to reply to your last post (Regarding the linker options). I don’t think that you missed some linker options, if you have the ones given “–specs=rdimon.specs –specs=nano.specs”.
I recreated the project based on the above tutorial and I didn’t see any problems (Besides some problems with the “Application Code”, as the one in this posting currently is having some trouble .. So I used the code from github.)
Previously I had the same problem, with the code getting stuck in the “mallocFailed” hook, but this was due to the “wrong” scheme (The FreeRTOS component used has the default set to “Scheme 2” and for some reason it always got stuck in the failed hook). After changing the scheme to “Scheme 3”, regenerating the Processor Expert Code and recompiling everything it worked okay.
Regards
Frank
LikeLike
Another thought I have: I’m using the 4.9q2 GNU ARM Embedded toolchain, and that might have an impact. Using heap Scheme3 means that the normal malloc()/free() is used, and and the FreeRTOS heap size has no effect. Instead, the heap needs to be allocated somewhere. I have now set the heap size in Processor Expert CPU component > Build Optiosn > Generate Link File > Heap Size to 0x2000 (8 kByte). The heap size is defined usually in the linker file with HEAP_SIZE, so make sure you have at least 8 KByte allocated there.
LikeLike
I have my build option set to HeapSIze 0 in the CPU component in processor expert and it still works.
Andreas
LikeLike
lwIP has defined its own heap size in lwipopts.h:
#define MEM_SIZE (12*1024)
and has in opt.h a setting to use its own malloc (and not the one from libc):
/**
* MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library
* instead of the lwip internal allocator. Can save code size if you
* already use it.
*/
#ifndef MEM_LIBC_MALLOC
#define MEM_LIBC_MALLOC 0
#endif
So with this, lwIP is using its own heap for its data stuctures.
Still, with Scheme3 (using malloc()) FreeRTOS needs some heap from the clib.
I have in my linker file this:
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x2000;
where the 0x2000 comes from the Processor Expert CPU component.
Having a heap size set to zero, in my case the heap will start at 0x2000’0000 and just grow, without checking for the heap end (a problem in the _sbrk() implementation I have on GitHub). It actually should check against __HeapLimit 😦
LikeLike
Hi again
I have now tried to update the toolchain to 4.9q2 and it seems to work now.
Thanks again for all the answers!
regards
Andreas
LikeLike
Andreas,
Something to check (because it bit my team) is if you have included the sbrk() function replacement. The KDS SDK uses the GCC libraries to create a runtime. The version of sbrk in GCC does a test of the proposed heap top against the current stack pointer and will return error if they cross. With lwIP, each task has their stack allocated from the heap so this test will fail when your tasks try to malloc memory. The fsl_misc_utilities.c file has a version of sbrk() that will work with lwIP.
Note that Erich wrote an article about this last year:
https://mcuoneclipse.com/2014/03/16/freertos-malloc-and-sp-check-with-gnu-tools/
LikeLike
Hi
Yes I have this piece of code activated in main.c
#if 1 /* depending on the GNU tools and libraries, a custom _sbrk() is needed */
void *_sbrk ( uint32_t delta )
{
extern char end; /* Defined by the linker */
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &end;
}
prev_heap_end = heap_end;
heap_end += delta;
return (void *) prev_heap_end;
}
#endif
regards
Andreas
LikeLike
Hi all! This worked for me also! I had to add -z muldefs option to the linker settings as instructed above. Otherwise, the linker will complain about multiple definitions.
LikeLike
Hi
i have now tried the same code on my computer at home with another installation and it worked perfectly there. I have to look into what installation of the toolchain I have on the different computers. At least I have one installation where it works.
Thanks for all the tips about the problem.
Best regards
Andreas
LikeLike
Have you ever know about FNET? In my opinion it’s much better than lwip! But it have some problems with processor expert.
LikeLike
Hi Mat,
yes, I know about FNET and hear good things about it too. But never had the time to explore it.
LikeLike
Hi,
can one of you tell me which version of lwip freescale decided to package into the KSDK installation?
Can’t find a version number in the source files.
LikeLike
sorry, did not look careful enough:
lwIP TCP/IP Stack Description: A light-weight TCP/IP stack
Version: 1.4.1
Author: Swedish Institute of Computer Science
License: Open Source – BSD-3-Clause
Format: source code
URL: http://savannah.nongnu.org/projects/lwip/
Location: KSDK_1.3.0/middleware/tcpip/lwip
LikeLike
After attempting to follow along I discovered the version of Eclipse you used was not the same as the latest: PE 3.0+PE3.0.1 update +KSDK 1.3.0 with your components from this month along with the project from 11/13/2015, well the whole Git thing.
In your example the settings are in a spreadsheet like format the current version has tabs and windows and the setting names are not the same or missing.
Then I read about the issues with examples on MCUonEclipse and downloaded the projects.
The Project:
X#include “FreeRTOS.h”
?#include “semphr.h”
?#include “event_groups.h”
So I notice FreeRTOS doesn’t appear to be in your project?
Any thoughts?
LikeLike
I moved on from KDS 3.0 to DYI with 32-bit MARS.1 now the issue is worse:
Description Resource Path Location Type
Error in the inherited component settings (Runtime Counter LDD) FRDM-K64F_lwIP_FreeRTOS FRTOS1/Runtime Counter LDD Processor Expert Problem
ERROR: This component is not supported in Kinetis SDK project mode FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1 Processor Expert Problem
Generator: ERROR: There are errors in the project, please review components configuration. It is not possible to generate code. FRDM-K64F_lwIP_FreeRTOS Code Generator Processor Expert Problem
HW doesn’t support this feature (Counter direction) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Counter direction Processor Expert Problem
HW doesn’t support this feature (Counter restart) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Counter restart Processor Expert Problem
The component is not supported for selected processor (Component name) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Component name Processor Expert Problem
This interrupt is required (Interrupt) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Interrupt Processor Expert Problem
Type ‘xTaskHandle’ could not be resolved Events.c /FRDM-K64F_lwIP_FreeRTOS/Sources line 55 Semantic Error
Unassigned peripheral (Counter frequency) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Counter frequency Processor Expert Problem
Unassigned peripheral (Counter) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Counter Processor Expert Problem
Unassigned peripheral (Overrun period) FRDM-K64F_lwIP_FreeRTOS RTOSCNTRLDD1/Overrun period Processor Expert Problem
Invalid project path: Include path not found (D:MCUEclipseExampExamplesKDSFRDM-K64F120MFRDM-K64F_lwIP_FreeRTOSGenerated_CodeSDKplatformdevicesMK64F12startup). FRDM-K64F_lwIP_FreeRTOS pathentry Path Entry Problem
I can’t find any information is the project about this.
LikeLike
Hi Kevin,
I have not tried that project in my DIY Mars yet, but it seems to me that not all the necessary SDK/components are installed?
LikeLike
Hi Kevin,
Yes, FreeRTOS is in my project. If you have question marks for the includes, that means that the header files are not found (not generated yet?). That ‘table’ vs. ‘tabs’ view is a setting which is described here: https://mcuoneclipse.com/2014/06/20/switching-between-tabs-and-no-tabs-ui-in-processor-expert/
LikeLike
Thanks for the quick responce. When I restarted my new install of eclipse 32-bit it hung so I had to start it in a new workspace. I Imported the project and told it to MOVE the files this time and here are the new errors:
Description Resource Path Location Type
Invalid project path: Include path not found (C:UsersKevinwork32FRDM-K64F_lwIP_FreeRTOSGenerated_CodeSDKplatformdevicesMK64F12startup). FRDM-K64F_lwIP_FreeRTOS pathentry Path Entry Problem
That is it, one error, so the ‘linking’ thing is doing something.
If I leave Eclipse running all the time I can save and make changes but when I close it, when it restarts and tries to open the project it hangs without leaving a .log file. Does it in 32/64-bit on my workstation and my PC with only one CPU and a SLED drive.
Both computers have Windows 10.
LikeLike
Hi Kevin,
I’m not running Windows 10 (I only have it on an old notebook installed for tests), but have not seen something like this. You don’t need to move/copy the files, simply import it into the workspace (no need for copy). Does that path/folder exist on your system? Maybe there is a Windows 10 security setting or something preventing the compiler to find that path?
LikeLike
I think I FINALLY found the problem with the ‘HANG’ while starting Eclipse: Close all Projects before exiting. I have hunted around but have not found anything about exiting Eclipse. More on this in a few days after it runs for a while, both the 32 and 64 bit version.
When I first Imported the Project FRDM-K64F_lwIP_FreeRTOS I didn’t check the Copy projects into workspace option and that choice caused many errors with the ‘path’. The location was D:MCUEclipseExampExamplesKDSFRDM-K64F120MFRDM-K64F_lwIP_FreeRTOS
When I Imported the Project FRDM-K64F_lwIP_FreeRTOS with Copy checked I only got one error:
Invalid project path: Include path not found (C:UsersKevinmcu64FRDM-K64F_lwIP_FreeRTOSGenerated_CodeSDKplatformdevicesMK64F12startup).
Since I’ve never generated code maybe that’s the problem?
Note: This path is R/W/X for Eclipse.
LikeLike
Hi Kevin,
this is definitely strange, and not something I have ever seen 😦
LikeLike
Very cool article. I did something similar using IPv6: http://fixbugfix.blogspot.com/2015/12/lwip-ipv6-on-k64f.html . Cheers!
LikeLike
Hi Michal,
thanks for providing that link, very useful!
LikeLike
Erich,
Great. In this example is your Freedom Board server or client?
LikeLike
It is used as client.
LikeLike
I see some errors when compiling
../Generated_Code/UTIL1.h:844:1: error: unknown type name ‘byte’
../Generated_Code/UTIL1.c:2039:1: error: unknown type name ‘byte’
multiple definition of `_write’
multiple definition of `_sbrk’
LikeLike
Hi Chad,
the first two problems are caused by an oversight on my side :-(. There is an updated utility module available on https://sourceforge.net/projects/mcuoneclipse/files/PEx%20Components/.
The errors about _write() and _sbrk(): I think you have still the SDK version of these in your project?
LikeLike
Erich I use KDS 3.0.0 with PE Components 2016-02-07 and KinetisTools_09.02.2016 installed but still get “error: unknown type name ‘byte’” when trying to use GenericSWSPI component. Is there an update dealing with missing typedef?
LikeLike
Are you using the component in a Kinetis SDK project? The Kinetis SDK is not compatible to anything else.
LikeLike
I have removed the bytes from the files (available in next release). Still it does not solve the need for non-SDK projects.
LikeLike
I wasn’t aware that I can’t use your components pack with Kinetis SDK.
Thank you!
LikeLike
you *can* use many of my components with the SDK. But as soon as components need low level hardware functions, currently they SDK does not allow that. I plan to post in the next weeks a few articles how I think it is possible to workaround the SDK.
LikeLike
Hi Eric,
Excellent article!
Have you ever considered creating an embedded component for lwip?
Id like to try to do it myself, but it might be a long learning curve for me.
Any suggestions?
Best regards,
LikeLike
Hi Camilo,
yes, I have considered that already multiple times. But I had not had the bandwidth for doing it 😦
Erich
LikeLike
Hi Erich,
Maybe we can use interleaved sampling 🙂
Do you happen to work for NXP? My company have a good relationship with Freescale, now NXP. We are a design house specialized in IoT products and we’re based in Brazil.
Best Regards,
LikeLike
Hello Erich,
I tried your tutorial to use the ethernet connection of the FRDM – K64F !
For all setup I haven’t had any problems but during the development of your application code I just get to see the “Welcome to the world of lwip ” in my P & E Semihosting Console…
And I would like an IP address of my card is that possible?
thank you for your time
LikeLike
You could use DHCP so it gets the address from the DHCP server?
LikeLike
I plug my card to a netgear router WGR614v9 that has a DHCP, but he doesn’t give IP at my FRDM 😦
LikeLike
I’m having some trouble with the very first step; Pin Settings. I have installed Design Studio (3.2.0), I have built an SDK using the online NXP Kinetis Expert System Configuration Tool (SDK_2.0_FRDM-K64F), created a new project in Design Studio and pointed it at the SDK (note: the Rapid Application Development dialog did not appear), downloaded the latest mcuoneclipse components (Components 2016-02-07) and imported both files by selecting Processor Expert –> Import Component(s) from within Design Studio. I added the components to “My Components”. I also selected Processor Expert –> Show Views. I built the project (FRDM-K64F_lwIP_FreeRTOS) which was successful. Once I select the project, the Components view is no longer greyed out. The issue is that I cannot see anything in the componeents view. There is another view which shows my component library. Under My Components there are folders for CPU External Devices, CPU Internal Peripherals, Operating System, Software and SW. At the bottom of this view I see; “No project focused, filtering disabled”. Any suggestions? I’m keen to work through this project, then have a go at building my own Eclipse IDE. I assume I can do this in Linux?
LikeLike
Hi Matthew,
yes, you can do this thing on Linux too. As for your problem that Processor Expert (Rapid Application Development) did not show up: the thing is that NXP does not include it with the SDK v2.0, see https://mcuoneclipse.com/2016/01/29/first-nxp-kinetis-sdk-release-sdk-v2-0-with-on-demand-package-builder/
So if you want to do this as in this post, you need the SDK v1.3 and not the SDK v2.0
LikeLike
Hi Erich. Thank you for your quick response. What I am trying to do is learn FreeRTOS. I will soon be using it on a STM32 (custom made board) but right now I have a K64F. Which is what brought me to your post. I would prefer to setup my own IDE (ideally Eclipse) so I fully understand what i’m using and how it all pieces together. I see in your post on setting up an Eclipse IDE that you also use version 1.3 of the SDK. For my first time setting this up, do you recommend I start with v1.3? Also, I assume your course materials are not publicly available?
LikeLike
Hi Matthew,
on FreeRTOS.org there are pretty good tutorials, plus there is a FreeRTOS guide you could get from there. And yes, it is pretty easy to setup your own IDE. As for the SDK: I recommend the v2.0. The v1.3 is difficult to use and understand. But it is up to you.
LikeLike
And about the course material: I have not published that to the public, and it probably does not make a lot of sense. Because there is are a lot of black/whiteboarding and labs in the course. So without being there, it does not make much sense. but maybe you could register for the next university course? 😉
LikeLike
Hi Erich
First of all thanks for this Tutorial. I am new to this world of Kinetis. I come from MSP430 world.
I did all the steps as you have explained. But when I compile I get an error of make
makefile:79: recipe for target ‘FRDM-K64F_lwIP_FreeRTOS.elf’ failed
make: *** [FRDM-K64F_lwIP_FreeRTOS.elf] Error 1
Probably is one configuration that I´ve missed, but I can´t find what I did wrong.
Regards Fernando from Buenos Aires Argentina
LikeLike
Hi Fernando,
Welcome to the ARM world! Are you using the latest project and files from GitHub? have you generated Processor Expert code first (right click on the .pe file in the project root, then use ‘Generate processor expert code’)? Other than that, make sure you have done a ‘clean’ (select the project, then use the menu Project > Clean.
I hope this helps,
Erich
LikeLike
Hi Erich,
Thanks for your response. I will try from zero playing attention to the points you have mentioned.
Regards
LikeLike
the guys developing lwip have been hard at work and are close to a 2.0 release.
they created a tag named “STABLE-2_0_0”.
http://git.savannah.gnu.org/cgit/lwip.git/log/?h=STABLE-2_0_0
I haven’t read/heard anything about the changes it contains but from the git log I can see that extensive work has gone to the dual stack support and code quality.
my goal is to migrate to this version the next days.
LikeLike
Hi Erich,
It is a great article.
I tried to run this project. I built it on a DIY Eclipse but Neon instead of Mars and with all of the current components:
The current NXP custom built 1.3 SDK doesn’t contain the \middleware\tcpip\rtcs directory at all, so I needed to install the old standalone release.
I’m using the Segger J-Link firmware and drivers as I can’t install the P&E Eclipse plug-in on the CDT 9.1
And my problem:
The board starts with the compiled code but it hangs in the very moment when it receive the IP address from DHCP. So I see three “LwipInitTask : Current DHCP State : 6” messages, than nothing. If the ethernet cable removed, it goes further and finish the DHCP round with timeout.
I tried the ENET_RECEIVE_ALL_INTERRUPT solution you mentioned, but it make it worst. The DHCP request process not even start. If I pause the debugger when the DHCP hanged, it stops in the port.c line 896:
configASSERT(((*portNVIC_INT_CTRL) & portVECTACTIVE_MASK)==0);
Do you have any idea, what could be the problem?
Thanks,
Zoltan
LikeLike
Hi Zoltan,
Using Neon should not make a difference. But are you using a different compiler too? That might make a difference, even a possible compiler bug?
I have not upgraded or changed the SDK for that project, so it sounds based on your feedback there are problems with the newer SDK.
That assert means that the interrupt priorities of FreeRTOS and the interrupts of the system are not configured properly. What it means is that you called an API function which is not supposed to be called from an interrupt. See https://mcuoneclipse.com/2016/08/28/arm-cortex-m-interrupts-and-freertos-part-3/ and the part 2 and 1 of the series about the ARM Cortex interrupt system.
I hope this helps,
Erich
LikeLike
Hi Erich,
Thank you for your answer. I tried to use the actual gcc: 5.4 2016q3. Then I reverted on project level to the 4.9 2015q2 as it was mentioned earlier in the comments.
I’ll give a try to changing it on wrokspace level, who knows what mistake I mad with it.
Regarding the SDK I’ll try to change it to the standalone 1.3 as I seen differences between the standalone and the built one.
Thank you for the interrupt articeles, I’ll read through, hopefully I’ll get some thoughts to the right direction.
Regards,
Zoltan
LikeLike
Hey Erich, I’m having a problem with the main. It’s giving me an error on this part:
void *_sbrk ( uint32_t delta ) {
extern char end; /* Defined by the linker */
static char *heap_end;
char *prev_heap_end;
if (heap_end == 0) {
heap_end = &end;
}
prev_heap_end = heap_end;
heap_end += delta;
return (void *) prev_heap_end;
}
#endif
The report is:
c:/freescale/kds_v3/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7e-m/fpulibrdimon_s.a(rdimon-syscalls.o): In function `_sbrk’:
syscalls.c:(.text._sbrk+0x0): multiple definition of `_sbrk’
./Sources/main.o:C:Userselivaworkspace1.kdsCONTROLADOORDebug/../Sources/main.c:77: first defined here
collect2.exe: error: ld returned 1 exit status
Can you help me?
LikeLike
Hi Elivander,
if you already have a working _sbrk() implementation, then simply remove/comment the one in main.c
I hope this helps,
Erich
LikeLike
Thanks for your reply Erich. This is my first time wornking with FreeRTOS and Embedded. So now I’ve got a problem, when I compile and debug is executing and stoping at this point if I connect the Ethernet wire:
“P&E Semihosting Console
Welcome to the world of lwip!
LwipInitTask: lwip init called ..
LwipInitTask : Started DCHP request (Ok.)”
I’m trying to use this board to my University Project, but it is so difficult for a beginer.
LikeLike
I’m affraid, but you have to step through the code to find out what is going on. I recommend that you use the board first with a dedicated small network (e.g. just with a router and the board attached).
LikeLike
Thanks Erich, I just downgrade the FreeRTOs to V8.2.2 and now the code is runnig.
LikeLike
Hello Eric Sir,
It is a great article.
I tried to run this project. But I am not able to debug the code as I am getting following statement on console window:-
CMD>RE
Initializing.
Target has been RESET and is active.
and aside main window I am getting this:-
No source available for “0x540”
I am using OpenSDA debugger… on FRDM K64f board…
Thank you…
LikeLike
‘OpenSDA’ debugger does not tell me much, as it could be P&E, Segger or CMSIS-DAP (do not use CMSIS-DAP would be my recommendation).
Have you debugged your application, does it reach main()?
Other than that, you have to debug/step through your code to find out what is going on. And avoid any printf() calls.
LikeLike
Hi Erich, nice article.
It´s my first time using processor expert, I used to do the initialization by myself but this is a lot more confortable.
I´m following your guide, but I got a problema while compiling the project, it says:
fatal error: fsl_os_abstraction_bm.h: No such file or directory
I noted that this abstraction_bm file is the one that is shown up in the confirmation dialog after making the processor expert code, don´t know if thats the cause of the problem.
Hope you have any idea about this error.
LikeLike
Hi Jorge,
it seems that you are using the Kinetis SDK OS version. In that case, you need to have that fsl_os_abstraction_bm.h file present in your project.
I would first try to regenerate processor expert code (context menu on the .pe file).
I hope this helps,
Erich
LikeLike
Pingback: Easter Weekend Apple Juice Brined Pulled Pork Smoked on Beech Wood | MCU on Eclipse
I’d like to use lwIP with MQX project without FreeRTOS, Is it possible to do it without using processor expert?
LikeLike
I don’t see why this would not be possible?
LikeLike
Hi Erich,
I tried to follow the tutorial but come to a problem:
I used the same setup, with difference to use your newest MCU components with FRTOS 10.1.1 and KDS 3.2 with SDK 1.3.
When running the program I got stuck at “LwipInitTask : Started DCHP request (Ok.)” like an another post here before.
It stopps at configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
I debugged and found out to set the ethernet-receive interrupt to a higher level than MaxSysCallPriority helps. So I added this:
NVIC_SetPriority(ENET_Receive_IRQn, 5);
And the program runs now. But I have doubts it is a good Idea to have the enet rx interrupt at such a low priroity in application.
You have maybe a idea to work arround? I could provide my project file if it helps.
br, Hans
LikeLike
Hi Hans,
Basically, the
configASSERT( ucCurrentPriority >= ucMaxSysCallPriority )
indicates that an RTOS API function got called from an interrupt which is not maksed by the RTOS.
See starting point in https://mcuoneclipse.com/2016/08/14/arm-cortex-m-interrupts-and-freertos-part-1/
So if you have an interrupt with priority numerically lower than ucMaxSysCallPriority (more urgent) and it uses RTOS functionality, this is not going right.
So setting that interrupt to numerically higher (lower urgency) is the correct way.
Your doubt is correct, but if that interrupt uses RTOS functions, it is the only way to be correct.
I recommend that you have a read at https://mcuoneclipse.com/2016/08/28/arm-cortex-m-interrupts-and-freertos-part-3/ too as this explains the need for this.
I hope this helps,
Erich
Erich
LikeLike