FreeRTOS with Stellaris LM3S9D92 and LWIP

barryandrews wrote on Thursday, July 19, 2012:

Hello

I am new to this forum and looking for an example of the LWIP with FREERTOS on stellaris LM3S9D92 processor.
I have searched the forum but keep getting circular references, none of which lead to an actual example.

I have downloaded the latest FreeRTOS and looked in the demos and there doesn’t seem to be one with LWIP and Stellaris, there are a few with lwip.

The TI example code with stellarisware has an LWIP example (1.3.2) but it is designed for safertos in the ROM and not for the FreeRTOS.  This means the sys_arch.c and sys_arch.h files are not suitable for FreeRTOS so I want an example so I know what to change.

The whole process is complicated for me because all the include files for this project come from multiple root paths, so working out where an include file lives is very hard.

I am using CCS V5 and can compile LWIP to run without RTOS and can compile and run FreeRTOS without the LWIP, now I want to combine these.

Any assistance and pointer to actual source code would be appreciated.

rtel wrote on Thursday, July 19, 2012:

The most recent lwIP/FreeRTOS integrations are the FreeRTOS+IO featured demo (which includes file system, CLI, etc.) and the demo that uses the FreeRTOS Win32 simulator found in the FreeRTOS interactive site (note that one uses an out of date CLI).

To get lwIP running with FreeRTOS requires two port layers:

First, FreeRTOS has to be integrated with lwIP - and this port layer is not dependent on the architecture, so you can just take that from an existing demo.  Look at the sys_arch.c files in the FreeRTOS/Demo/Common/Ethernet/lwip-1.4.0/ports subdirectories.

Second, lwIP has to be ported to the Ethernet hardware.  For this you have to provide the low level input and low level output functions, which you will find in the ethernetif.c files in the same directories.  You can copy the passing of frames into and out of the stack from those files too.

If you take one of the existing FreeRTOS demos (use the two mentioned above for up to date versions of lwIP - older versions had different semantics) you should be able to get the low level Ethernet interfacing functions from you already working lwIP (without FreeRTOS) code.

Regards.

barryandrews wrote on Thursday, July 26, 2012:

Thanks for the information.

I now have lwip 1.0.4.0 compiling and running without an RTOS on my system.
However when I try to combine the lwip with the FreeRTOS I get an error in sys.h

the compiler says that sys_prot_t is not defined.
When there is no system this is defined as u8_t.
I cannot find where it is defined when the FreeRTOS is included?

sys_prot_t is used in the sys_arch.c files but doesn’t seem to be defined in any of the include files in either example with the freeRTOS.

barryandrews wrote on Friday, July 27, 2012:

I have sorted out the sys_prot_t issue, it’s defined in cc.h under the lwip 1.0.4.0 example in FreeRTOS.

I am having trouble with the initialisation of LWIP with FreeRTOS.
The example I started from under CCSV5 was the LWIP exaple which is setup to work with the SafeRTOS in one of the Stellaris chips.  Problem is this is not the same as the way FreeRTOS works so this makes it hard to know where to initialise a task for the thernet and how to initialise it.  I can get LWIP to run on it’s own by setting NO_SYS=1 but that removes any FreeRTOS.  I can get FreeRTOS to run on it’s own but searching through the entire FreeRTOS demo examples doesn’t give me anything like the way TI have implemented for their LWIP with SafeRTOS.  Any clues would be appreciated!

rtel wrote on Friday, July 27, 2012:

It is not clear to me what you are not finding in the FreeRTOS examples.  If you let me know which example you are looking at I can let you know where lwIP is initialised, and where the task that runs the stack etc. is created.

Regards.

barryandrews wrote on Friday, July 27, 2012:

Thanks for the Response Richard

That’s my biggest problem, determining which example I should be referring to.
I am using LWIP version 1.4.0 and Stellaris processor LM3S9D92

Which example should I be using ?

rtel wrote on Friday, July 27, 2012:

That is not an example I have any knowledge of, so I can’t help with that one.

There are 1.4.0 examples for FreeRTOS that I created myself that I can direct you to.

First the FreeRTOS+IO featured demo:
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml

Or something more hardware neutral, the Win32 simulator demo (note the command interpreter in this example is obsolete and replaced with FreeRTOS+CLI):
http://interactive.freertos.org/entries/20290712-freertos-win32-project-with-lwip-web-server

Regards.

barryandrews wrote on Friday, July 27, 2012:

Thanks

Can you tell me one thing.
Where should the lwip timers be called from?

rtel wrote on Friday, July 27, 2012:

I don’t think that is something you have to worry about, the stack does it.  You just need to provide the port layer to the Ethernet hardware, and the port layer to FreeRTOS (which is in the code I just linked to).

Regards.

barryandrews wrote on Tuesday, August 07, 2012:

Still struggling with this abit.
Is there any example with FreeRTOS plus LWIP and the Stellaris LM3S9D92 so that I can see the Ethernet interface example.

The stellaris_if.c used in the stellarisware example uses different messaging to the FreeRTOS examples for thing such as microblaze, so this makes it hard to determine how to change the stellaris code.  For example low level output seems to be 2 routines in the stellarisware but only one in the microblaze and they don’t correlate.

Also the microblaze seems to be missing some functions which are probably library routines so I cannot compare how they write to their hardware vs writing to the stellaris ethernet port.

Thanks in advance.

edwards3 wrote on Tuesday, August 07, 2012:

Are you sure the example you are working on and the example you are using as a reference are both using the same lwIP version? If you are working on an lwIP version less than 1.4 I recommend updating to the latest. If you are using and earlier version and have to stay with it then there are some examples in the FreeRTOS download that also use earlier version that might help more as a reference.

mrandini wrote on Tuesday, August 07, 2012:

Both examples are for lwip 1.4.0 but Stellaris one is setup for SafeRTOS not FreeRTOS.
The lwip works fine with no RTOS but not with FreeRTOS.

Hence I am looking for a LM3S9D92 Stellaris example without much luck, or even LM3S9B92 would be great as they have same ethernet controller.

anonymous wrote on Friday, August 10, 2012:

You should probably try the cortex_LM3SXXXX_Eclipse demo.  It’s not the same chip but the changes so it would run on
the LM3S9D92 should be minimal (flash size and ram size). 
Those are in the standalone.ld file.

Also look at http://www.freertos.org/portLM3Sxxxx_Eclipse.html since that is the documentation page for the demo.

barryandrews wrote on Friday, November 02, 2012:

Hello, finally got back onto this and have at least made some progress but still getting forced hard fault exceptions.
These seem to be associated with the enable interrupts function but I don’t understand why.

In my FreeRTOSCOnfig.h I have

#define configKERNEL_INTERRUPT_PRIORITY         ( 7 << 5 )  // Priority 7, or 224 as only the top three bits are implemented.  This is the lowest priority.
#define configKERNEL_SVCALL_INTERRUPT_PRIORITY  ( 5 << 5 )  // Priority 6, or 192 as only the top three bits are implemented.  This is the lowest priority.
// !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
// See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html.
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( 5 << 5 )  // Priority 5, or 160 as only the top three bits are implemented.

I put the SVCALL priority there so I could adjust it’s priority separate to the other two.
However if I set the SVCALL priority to anything other than lowest (0) I get an exception when I try to start the first task.
I have tried setting SVCALL Priority to 0,1,5,6,7
If I leave it at 0 I can launch the first task and tasks run till I get an exception when the tcpip task first checks for any messages and uses gettickcount which does a enable interrupt call after reading the tick count.  This causes a imprecise fault.  Stting the SVCALL priority to anything other than 0 causes a forced hard fault.

	// Make PendSV and SysTick the same priority as the kernel.
   *(portNVIC_SYSPRI3) |= portNVIC_PENDSV_PRI;
   *(portNVIC_SYSPRI3) |= portNVIC_SYSTICK_PRI;
	// Make CallSV the same priority as the kernel.
   *(portNVIC_SYSPRI2) |= portNVIC_SVCALL_PRI;	

I found the example I was working from was in fact writing to the wrong register for the Systick and PendSV.
I have now confirmed from the debugger that all of these write to the correct registers and the correct bits so I can check the NVIC and see the correct settings after xPortStartScheduler is called.
I have left the priority for all other interrupts at the default as this is what is in the LWIP 1.4.0 example I copied from.

I have read the FreeRTOS article on the interrupt priorities and am using what I think is correct levels, but still these exceptions.
Just for safety at the moment I have also pushed all my stacks out to 2048 bytes.

davedoors wrote on Friday, November 02, 2012:

I found the example I was working from was in fact writing to the wrong register for the Systick and PendSV.

I assume that was not an official FreeRTOS port then.

barryandrews wrote on Friday, November 02, 2012:

Yes it was from a freertos port

GCC/ARM_CM3

port.c

/* Constants required to manipulate the NVIC. */
#define portNVIC_SYSTICK_CTRL ( ( volatile unsigned long *) 0xe000e010 )
#define portNVIC_SYSTICK_LOAD ( ( volatile unsigned long *) 0xe000e014 )
#define portNVIC_INT_CTRL ( ( volatile unsigned long *) 0xe000ed04 )
#define portNVIC_SYSPRI2 ( ( volatile unsigned long *) 0xe000ed20 )
#define portNVIC_SYSTICK_CLK 0x00000004
#define portNVIC_SYSTICK_INT 0x00000002
#define portNVIC_SYSTICK_ENABLE 0x00000001
#define portNVIC_PENDSVSET 0x10000000
#define portNVIC_PENDSV_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 16 )
#define portNVIC_SYSTICK_PRI ( ( ( unsigned long ) configKERNEL_INTERRUPT_PRIORITY ) << 24 )

For the texas instrument lm3s9b92
Which is cortex m3

(SYSPRI1), offset 0xD18
(SYSPRI2), offset 0xD1C
(SYSPRI3), offset 0xD20

SVC is in syspri2
Systick and svpend are in syspri3

So it works because the address is right for syspri3 which is where the bits need to be set but confused me as when I checked the datasheet it didn’t match the description in the code.

Code also has incorrect comment

	/* Make PendSV, CallSV and SysTick the same priroity as the kernel. */
	*(portNVIC_SYSPRI2) |= portNVIC_PENDSV_PRI;
	*(portNVIC_SYSPRI2) |= portNVIC_SYSTICK_PR

I;

CallSV is not meant to be set, code doesn’t do it but comment says it is doing it, combinme that with incorrect register number and you can see my confusion.

I did some more checking of the examples I have been using.
Both TI and FreeRTOS ones.

What I think I may have as my problem is that my lwiblib.c file is for a lwip 1.3.2 demo and the rest is from lwip 1.4.0
I have been searching for a stellaris port with lwip 1.4.0 but cannot fine one which has the lwiblib.c file and its set of functions
which are basically the link between freertos and the hardware layer in ethernet.c or stellaris.c depending upon the example.

The freertos demos which include lwip are all very old versions of lwip

If you can point me to a good lwip 1.4.0 with freertos example (Preferably cortex M3) that would be great.

rtel wrote on Friday, November 02, 2012:

Just to be clear then - you are not saying the code is doing the wrong thing, just that the names and comments in the code are misleading.  I will check and update is necessary.

Yes, some lwIP demos are very old, in fact, some standard non lwIP demos are very old.  It is not practical to revisit each demo.  There are some lwIP V1.4.0 demos too though.  I think you will find one for the LPC1769 (Cortex-M3) here:
http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_IO/Demo_Applications/LPCXpresso_LPC1769/NXP_LPC1769_Demo_Description.shtml (demo 2).

Regards.

barryandrews wrote on Monday, November 05, 2012:

Hello Richard

Really appreciate your help so far, have downloaded the example you suggest, unfortunately cannot import this into ccsV5, gives an error, so have been going through and comparing what they have done, vs my attempt based on TI project.

None of these files have a makefile, so hard to see what the compiler/linker is actually including in the build.

In the TI example they have a file called lwiplib.c which includes just the files it wants from the lwip build.
I went through the options they use for this example but hit a snag.

in the sockets.h file there are macros for LWIP_COMPAT_SOCKETS

#if LWIP_COMPAT_SOCKETS
#define accept(a,b,c)         lwip_accept(a,b,c)
#define bind(a,b,c)           lwip_bind(a,b,c)
#define shutdown(a,b)         lwip_shutdown(a,b)
#define closesocket(s)        lwip_close(s)
#define connect(a,b,c)        lwip_connect(a,b,c)
#define getsockname(a,b,c)    lwip_getsockname(a,b,c)
#define getpeername(a,b,c)    lwip_getpeername(a,b,c)
#define setsockopt(a,b,c,d,e) lwip_setsockopt(a,b,c,d,e)
#define getsockopt(a,b,c,d,e) lwip_getsockopt(a,b,c,d,e)
#define listen(a,b)           lwip_listen(a,b)
#define recv(a,b,c,d)         lwip_recv(a,b,c,d)
#define recvfrom(a,b,c,d,e,f) lwip_recvfrom(a,b,c,d,e,f)
#define send(a,b,c,d)         lwip_send(a,b,c,d)
#define sendto(a,b,c,d,e,f)   lwip_sendto(a,b,c,d,e,f)
#define socket(a,b,c)         lwip_socket(a,b,c)
#define select(a,b,c,d,e)     lwip_select(a,b,c,d,e)
#define ioctlsocket(a,b,c)    lwip_ioctl(a,b,c)
#if LWIP_POSIX_SOCKETS_IO_NAMES
#define read(a,b,c)           lwip_read(a,b,c)
#define write(a,b,c)          lwip_write(a,b,c)
#define close(s)              lwip_close(s)
#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */
#endif /* LWIP_COMPAT_SOCKETS */

Trouble is that this is causing an issue in the lwip udp.c and tcp.c because the compiler replaces pcb->rcv with
pcb->lwip_recv and says that TCP_PCB and UDP_PCB both don’t contain a fiels lwip_recv

Is there anywhere which defines what files should be included in the project.
The lwip is confusing because includes say “lwip/xxx” and the directory structure has a couple of different lwip/directories, so unless your compiler is setup for the correct include directories it is hard to know if you are actually including the correct file?

Any suggestion how to overcome this one?

barryandrews wrote on Tuesday, November 13, 2012:

Finally got this to all work on CCS but am getting a fault in FreeRTOS after running for a while with heavy packet loads on the LWIP.

I have ensured that both FreeRTOS and LWIP heaps are well and truly big enogh to not get trashed.

However what I have found is that somehow the pxCurrentTCBConst is getting trashed (set to 1) and this causes an exception when the xPortPendSVHandler switches to the next context.

Any suggestions as to why this may occur?

rtel wrote on Tuesday, November 13, 2012:

I don’t know how you have written your CCS port, but in the GCC port (which is the only place pxCurrentTCBConst appears) the pxCurrentTCBConst value is just that - a constant.  It is part of the executable image, so assuming you are running from flash and not RAM, it cannot change.

Are you running from RAM?

Regards.