This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LwIP compatibility with HALCoGen 03.08.00

Other Parts Discussed in Thread: HALCOGEN

Hi everyone,

Simple question,

I saw that in the HALCoGen 03.08.00 the hdkif + emac has merged into a single file (emac).

The emac.c is compatible or can be made compatible with LwIP? Or follows a different structure?

My reason for use the LwIP is the sockets

Thanks,

  • Victor,

    Thank you for using our forum.

    Your question has been forwarded to our Halcogen Team. They will be back to you shortly.

  • Victor,

    It's true that the initialization, transmit and receive APIs have been adapted from hdkif in the lwIP demo, but the generated EMAC drivers in HALCoGen are only basic low level drivers with APIs supporting the various functionalities of the module. It does not offer any particular compatibility/support for LWIP. You will have to do that on your own.

    For reference, however, you can use the HALCoGen- lwIP demo. It was made with HALCoGen 3.06, but you can replace the generated driver code with code from 3.08.

    Hope this helps.

    Thanks and Regards,

    Chaitanya

     

  • Thanks for your reply Chaitanya,

    I want to make it run with FreeRTOS so the example is not really valid.

    I will try to make it compatible and see what happens.

    For avoid time and possible questions, I still have to follow the porting, right?

    http://processors.wiki.ti.com/index.php/HALCoGen_Ethernet_Driver_and_lwIP_Integration_Demonstration.

    Im speaking specially about change the PLL frequencies.


    Thanks,

  • Victor, 

    Yes, I think you still have to follow the porting procedure, including changing PLL frequencies and pinmux settings and all that. If you do port lwIP with FreeRTOS, please post some of your work on the forums for the reference of others. If you're allowed to, that is.

    Thanks and Regards,

    Chaitanya

  • Hi guys,

    After a couple of days debugging I think I found the main issue with the lwIP.

    The last version of the HDK + FreeRTOS uses swi hanlder and locks the core constantly, this provokes that the EMACRxIntISR/EMACTxIntISR will NEVER be called.

    The easy solution is make sure that you have the interrupts enabled when you expect an interrupt.

    This should fix the problem to those who can't get a DHCP address or those who can't make lwIP work properly with the v03.08.00 and 01.

    #if LWIP_DHCP
    if(ipMode == IPADDR_USE_DHCP)
    {
    unsigned int dhcp_flag = 0;
    unsigned int dhcp_tries = 5;
    unsigned int count;
    unsigned int delay;
    while(dhcp_tries--)
    {
    dhcp_start(&hdkNetIF[instNum]);
    __enable_irq();
    count = 10;
    /* Check for DHCP completion for 'count' number of times, each for the given delay. */

    HALCoGEN guys, please check this change and ask me the code if you need more info so we share information and make a stable version.

    In the next step I'm going to try to implement the sockets.

  • Victor,

    I didn't completely follow what you said and have a few questions:

    1. What exactly do you mean by "swi hanlder locks the core constantly"? Do you mean that the interrupts are never serviced or that interrupts get disabled?

    2. Interrupts are already enabled right before calling the lwIPInit() function. Are they getting disabled by the SWI handler such that they need to be enabled again?

    3. Is this lwIPInit function called within a task or during initialization before a task?

    Please do clarify. I do not have too much knowledge of FreeRTOS and thus would appreciate any information.

    Thanks and Regards,

    Chaitanya

  • Hi Chaitanya,

    I'm not an expert with this library and FreeRTOS but this is what I think it happens:

    In the lwIP Example you have to enable the IRQ and FIQ for make the interruptions work properly, thats fine

    The problem is that when you use the FreeRTOS with the lwIP,  the lwIP calls a function called "SYS_ARCH_PROTECT", which calls "taskENTER_CRITICAL" . and more and more wrapps.

    Finally you end with "swiPortEnterCritical" , I presume that this what actually does is prevent the interruptions to be called. For some reason, the interruptions never back to be enabled.

    Thats why I was wondering if someone can double check that what I'm saying is correct. The questions is that I've been reading forums and googeling and I couldn't find anyone who could implement FreeRTOS + lwIP defining "NO_SYS" as 0.. (So using FreeRTOS as OS).

    So if someone can confirm this would be nice, if they can't well.. it works for me!

    So now answering your questions:

    1. What exactly do you mean by "swi hanlder locks the core constantly"? Do you mean that the interrupts are never serviced or that interrupts get disabled?

    I think that the interrupts get disabled when the OS tryies to enter in a critical operation, and they never become enabled again or at least not when they should.

    2. Interrupts are already enabled right before calling the lwIPInit() function. Are they getting disabled by the SWI handler such that they need to be enabled again?


    Thats what I think its happening, otherwise might be not being enabled when they should. The fact is that enabling the interruptions it works. And I tried to don't modify the code at all.

     

    3. Is this lwIPInit function called within a task or during initialization before a task?

    No scheduler working, just the lwIP example using the FreeRTOS OS (So managing the semaphores, mutex, and I think the core locking).

    I tried to keep really clean the code, no weird modifications.

  • Hi Victor,

    Thanks a lot for the detailed explanation. I'm  not sure if it's entirely correct since "SYS_ARCH_PROTECT" is called even in the NO OS context (NO_SYS =1). Interrupts are re-enabled at the end of the critical section, so it ought to work. But like you said, your fix seems to be working.

    Could you please share your code here (the full project)? I'll try looking into it to see if I can think of anything else, and also for anyone else who's trying to port FreeRTOS and lwIP.

    Thanks and Regards,

    Chaitanya

  • When you say NO_SYS = 1 you avoid FreeRTOS to manage your lwIP library, this means that the system won't enter in any critical situation.

    If you say that you don't have OS, FreeRTOS won't manage the critical situations, due in the sys_arch.c you will just have 

    sys_prot_t
    sys_arch_protect(void)
    {
      sys_prot_t status;
      status = (IntMasterStatusGet() & 0xFF);
    
      IntMasterIRQDisable();
      return status;
    }
    

    So this works fine, no problem.

    The problem comes when I use the sys_arch.c for FreeRTOS, by default does:

    sys_prot_t sys_arch_protect( void )
    {
    	if( xInsideISR == pdFALSE )
    	{
    		taskENTER_CRITICAL();
    	}
    	return ( sys_prot_t ) 1;
    }

    and when tries to exit does

    void sys_arch_unprotect( sys_prot_t xValue )
    {
    	(void) xValue;
    	if( xInsideISR == pdFALSE )
    	{
    		taskEXIT_CRITICAL();
    	}
    }

    And there is where we have a problem, again taskEnter_Critical disables some interrupts, those interrupts never back to be enabled again.

    Well, not I'm not saying that TI did their critical management wrong, just that the porting doesn't work for the interrupt reason. The sys_arch has been created for be ported to any platform. This (theorically) works with any device with FreeRTOS configured, but if Im not wrong noone could use FreeRTOS + lwIP + TMS570/RM48, right?

    I'm not sure if I can't post the code due that this work is for a commercial product, so If I see that I can will post it.

    Look this post:

    http://e2e.ti.com/support/microcontrollers/hercules/f/312/t/190805.aspx

    Have a look into the post, you will find that she couldn't make work the lwIP + FreeRTOS. TI told him to put NO_SYS = 1. That was the TI solution (which is not a solution). But if we put NO_SYS = 1. Then there is no multitasking so no TCP/IP and no sockets.

    So its easy, create a project as HDK + FreeRTOS, follow the Texas Instruments instructions for configure the lwIP (http://processors.wiki.ti.com/index.php/HALCoGen_Ethernet_Driver_and_lwIP_Integration_Demonstration). Put the NO_SYS as 0 and try get a DHCP address. 

    Can you get a DHCP? No? Then enable the interrupts manually after start the dhcp (_enable_irq() or __enable_irq() ) and try it again

      dhcp_start(&hdkNetIF[instNum]);
      __enable_irq();

    I'm sure TI already tried to implement FreeRTOs + lwIP and they couldn't im triend to throw some light. I hope it helps.

    I will post my lwIP library.

    LWIPFREE.rar
  • Hi Everyone.

    So I have the TCPIP Threading  (FreeRTOS) working with DHCP but with memory problems.

    Now I have the following Issue, this is about the FreeRTOS port.

    The last port to FreeRTOS 7.4.0 using MPU and vPortSWI makes the system go really really slow.

    Im trying to port to the FreeRTOS 8.0.0 and the speed is considerable, the lwIP multithread with TCPIP and DHCP works but after some time I get a memory corruption, this could be because my portasm.asm is not really good (as has been fixed by me and Im not an expert).

    So here comes my question, is normal that the vPortSWI takes so long for execute each instruction? Its possible to back to use the vPortYieldProcessor instead the vPortSWI?

    In fact, if you enable  "SYS_LIGHTWEIGHT_PROT" you will notice that even the single thread of IP with DHCP won't work, because the system is "too slow". However with the vPortYieldProcessor  of the FreeRTOS 8.0 it gets the DHCP in IP and TCPIP with the "SYS_LIGHTWEIGHT_PROT" enabled. I think the reason is that the system its faster.

    Can anyone throw me light on this? I know its a big text but I can explain it by parts

    Thanks

  • Hi Victor,

    Could you clarify your question please? Is it that you're noticing a speed increase by directly calling  vPortYieldProcessor  rather than going through vPortSWI? (since vPortYieldProcessor is called through the SWI anyway), or regarding the memory corruption? 

    Also, I have been told that one possible reason for slowness might be due to the MPU regions. While restoring context, MPU settings are set for each MPU region and this might take some clock cycles. There are 12 MPU regions in total of which 8 are used by tasks. So doing this for each task every time context is restored might be causing the slowdown.

    Hope that helps. Do give us more details about your exact question, we'll do our best to help.

    Thanks and Regards,

    Chaitanya

  • Hi Chaitanya.

    I will be clear, the FreeRTOS 7.4 - vPortSWI using MPU its too slow for work in multithreading, so my TPCIP Stack won't work properly. There is any possibility of make this faster? Avoiding the use of MPU regions?

    In other hand, there is any official documentation for the porting to FreeRTOS 8.0? Or any estimated date for the release? Its possible to find the port for CCS. Looking the port there are variables as "__TI_VFP_SUPPORT__" not defined by default. Before asking more about this, there is some work done that you could share? 

    Thank you.

  • Victor,

    One suggestion is that you could try using fewer MPU regions, instead of having to avoid using them entirely. 

    Also, there is no specific plan yet for a FreeRTOS v8 port, though it is in the pipeline. Did you use MPU even in the 8.0 port? What do you think is the reason for the observed speed increase?

    Thanks and Regards,

    Chaitanya

  • Hi Chaitanya

    I will try to use fewer MPU regions,

    The Cortex R4 included in FreeRTOS 8.0 doesn't include MPU wrappers. I have disabled the MPU with the HALCoGen so I didn't want memory protection. It uses the vPortYieldProcessor, now vPortSWI. I understand that the port included in the HALCoGen is more safe using the memory protection but I can't lose so many performance.

    In some point the memory gets corrupted, looking yesterday with other college of my team we discovered that when restores the task the register R14 is wrong, so the code ended doing a loop in the "Critical Nesting ++) overflowing the memory.. 

    Being more specific about your question, when I have running the FreeRTOS 7.4, when I stop the code "almost always" the code is running the vPortSWI. Puting a Log Breakpoint I can see how its more time using that piece of code than actually executing the normal code.

    For start the LWIP and get an IP address with DHCP takes me like 1 second without FreeRTOS.

    With FreeRTOS is 6 seconds.

  • Hi Victor,

    Thanks for the explanation. Maybe the MPU wrappers are adding a lot of delay, I can't be sure.

    Hope you find a suitable solution. 

    Thanks and Regards,

    Chaitanya

  • Hi.

    Finally solved and fully working.

    This thread can be closed or deleted.

    I decided to make a modification in the Critical Section Handling, but this might not be compatible with the MPU. 

    Some of my problems came for keep my old FreeRTOSConfig, I was using 80Hz as Clock Frequency when now we have to use 90Hz.