Software Timers in FreeRTOS v8.2

rtel wrote on Thursday, March 05, 2015:

Yes - that is the approach I would have taken too. Assuming the port is
known to be working, and malloc() is never failing, then I cannot think
of any reason why doing that would cause an issue. Even if the software
timer could not be created it should not crash or prevent you from
stepping into the code. Something is fundamentally wrong somewhere -
maybe you are ending up in a fault interrupt, or something like that.

One thing you could do is try switching to assembly mode and try
stepping into the function in assembly code to see what happens, or at
least how far into the function you get before the debugger lets go.

Which heap_x.c file is included in the project?
(http://www.freertos.org/a00111.html)

Regards.

gmgrpl wrote on Saturday, March 07, 2015:

I’m using Heap_4.c per the recommendations and I’m using BufferAllocation_2.c

gmgrpl wrote on Saturday, March 07, 2015:

After attempting to start the timer in prvIPTask and pausing the debugger, execution is always in the file sys_intvecs.asm at the prefetchEntry line:

;-------------------------------------------------------------------------------
; interrupt vectors

resetEntry
b _c_int00
undefEntry
b undefEntry
b vPortSWI
prefetchEntry
b prefetchEntry
b _dabort
b phantomInterrupt
ldr pc,[pc,#-0x1b0]
ldr pc,[pc,#-0x1b0]

Does this provide any clues?

gmgrpl wrote on Saturday, March 07, 2015:

I set a breakpoint at the call to xTimerCreate in prvIPTask() and disassembled into assembly instructions. I see the following, and when I step through these instructions on the branch to xTimerCreate (EBFFD8F8 BL xTimerCreate) the processor jumps to sys_intvecs.asm as I described in the previous post.

0000c490: E59FCE44 LDR R12, $C$CON2
0000c494: E3021710 MOVW R1, #10000
0000c498: E3A02001 MOV R2, #1
0000c49c: E3A03002 MOV R3, #2
0000c4a0: E28F0FF7 ADD R0, PC, #988
0000c4a4: E58DC000 STR R12, [R13]
0000c4a8: EBFFDBF8 BL xTimerCreate

You can see the parameters being loaded onto the stack: R12 has the timer name, R1 (10000) is the timer period, R2 (1) is autoreload, R3 (2) is eARPTimerEvent. I assume R0 is the address of the callback function. I’m not sure of the contents of R12.

rtel wrote on Saturday, March 07, 2015:

Are you sure you are not using an MPU port?

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0363e/I31997.html

Regards.

gmgrpl wrote on Saturday, March 07, 2015:

I am using an MPU port. I need to figure out how to turn it off in HALCoGen - a simple disable under the R4-MPU-PMU tab didn’t do it.

gmgrpl wrote on Sunday, March 08, 2015:

I guess I’ll have to contact TI as I can’t find a way to disable the MPU from HALCoGen. The HALCoGen GUI provides a tab for configuring the MPU and it appears as if it can be disabled, but the generated code doesn’t reflect disabling the MPU.

gmgrpl wrote on Monday, March 09, 2015:

I spent a little time today reading up on the ARM MPU and how HALCoGen configures it. I consulted the TI RM46x TRM, the ARM TRM, and the FreeRTOS documentation on the subject. After all that, I OR’d portPRIVILEGE_BIT with ipconfigUDP_TASK_PRIORITY in the source file FreeRTOS_UDP_IP.c on line #127 where the “prvIPTask” is created. This allowed me to get past creating the timer in prvTask without a prefetch error. I still don’t have the network stack working correctly yet, but I’ve gotten past a significant issue. Can you think of any other issues I should be on the lookout for?

Thanks for your help,

Ray

rtel wrote on Tuesday, March 10, 2015:

Hi Ray - good call with the portPRIVILEGE_BIT, the stack has probably
never been used with an MPU port before (very few FreeRTOS applications
will use the MPU, whereas very few SafeRTOS applications will not use
the MPU). I take it the code is no longer ending up in the abort
handler, but still you have no communications.

I would suggest the first thing to do would be to ensure the MAC driver
is receiving network data. If you put a break point in the MAC driver’s
interrupt, then send a ping to the board, does the interrupt ever
execute? [sending a ping to an unknown IP address should generate an
ARP message, which should be received by the hardware even if the IP
address is not assigned to the hardware].

Regards.

gmgrpl wrote on Tuesday, March 10, 2015:

I generated the port I’m using with HALCoGen v04.03.00. That version of HALCoGen uses FreeRTOS v8.2.0 - it doesn’t offer a choice about using the MPU.

I’ve just started the debugging process to figure out why the stack isn’t working. One of the things I’m trying to track down is how FreeRTOS handles the IP and MAC addresses. It appears the MAC address is handled correctly but the IP address is reversed somewhere, but I’m not 100% positive about anything yet.

I’m not sure the debugger allows breakpoints in an ISR, but I’ll figure out how to track data flow through the stack. I do have a question about the routine that I had to write: “xNetworkInterfaceInitialise”. It appears this routine can be called more than once - during initialization and whenever the network is determined to be “down”. I made sure the creation of “prvEMACDeferredInterruptHandlerTask” can only be called once, but initializing the hardware can be called more than once.

After looking at the source code HALCoGen generates for the EMAC device driver, I call “EMACHWInit” every time “xNetworkInterfaceInitialise” is called. Is this the correct way to handle that?

Ray

rtel wrote on Tuesday, March 10, 2015:

I’m not familiar with the code generated by HALCoGen, but if
xNetworkInterfaceInitialise() is only called when the network is down it
will be ok to call EMACHWInit() each time. Assuming EMACHWInit()
initialises the DMA descriptors any packets already held in the
descriptors would be lost of course. Also, if EMACHWInit() enables the
MAC interrupt it would be a good idea to disable the interrupt manually
before EMACHWInit() is called - if it does not do it itself inside the
function.

Regards.

gmgrpl wrote on Thursday, March 12, 2015:

I’ve got the UDP/IP stack running but I’m having problems. I have the stack configured to use DHCP for now. Using Wireshark I can see a DHCP Discover message go out from the RM46 and an offer comes back from the server. Next I see a DHCP Request go out from the RM46 and an ACK comes back from the server. After that I don’t see any more responses from the RM46.

Eventually the RM46 stops and the debugger reports that the ARM had an exception again. I assume I probably need to review the settings in FreeRTOS_UDP_IP.h. Originally FREERTOS_BIG_ENDIAN was defined to one and I was having very unstable behavior. I changed it to “0” and Set FREERTOS_LITTLE_ENDIAN to one. That seemed to help, but the stack is still very unstable. Do you have a recommended set of settings for configuration compatible with the RM46/48?

I want to use the UDP/IP stack in the simplest way - I just want to stream data on the network. When I’m not doing that I want the stack to not use unnecessary CPU cycles.

Thanks,

Ray

gmgrpl wrote on Thursday, March 12, 2015:

By the way, I’m not positive I’ve got the compiler settings correct for structure packing, etc. I’m using the TI v5.2.2 compiler.

Ray

gmgrpl wrote on Thursday, March 12, 2015:

OK, I tweaked some of the stack and buffer configuration settings and I was able to get the RM46 to accept a DHCP IP address from the server. I enabled outgoing pings and was able to get the assigned IP address using Wireshark. When I ping the IP address from my host computer I got responses as expected. After that I did an “arp /a” from the host and verified the RM46 showed up with the right IP and Ethernet address.

The RM46 runs a little longer after I tweaked the buffer and and stack configuration settings, but it still dies after just a few minutes. I assume this means I may have a memory leak somewhere (or a stack growth issue). I’m not using dynamic memory allocation to get data from the stack - I use statically allocated buffers and I verified I’m handling the indexing properly. Are you aware of anything in the stack that might be using memory if I didn’t configure it or set it up properly? If not, do you have any suggestions on how I can track down the leak (or stack growth) using TI’s CCS? I have no CLI or other way of seeing into the code.

Thanks for your help,

Ray

rtel wrote on Thursday, March 12, 2015:

I would suggest first determining if it really is a memory leak by first
defining a malloc failed
hook
, and then (if you are using one of heap_1.c, heap_2.c, heap_4.c
or heap_5.c) periodically calling xPortGetFreeHeapSize() to see how much
free space is available.

Also, which memory allocator are you using? If you not using heap_4
then it might be an idea (as an experiment at least) to switch to it as
it should prevent fragmentation of the heap as far as is viable.

Regards.

gmgrpl wrote on Friday, March 13, 2015:

OK. It tok me 12 days, but I finally have the FreeRTOS+UDP working on an RM46x HDK using the MPU. I did not implement a “zero copy” version, so it is not very efficient, but it works cooperatively with other tasks and meets my needs.

The last issue I had was putting data on a queue at ISR level. I knew there was a special command to put data on a queue at ISR level, I just hadn’t gotten around to using it. The hooks for malloc and stack overflow were very useful in helping me troubleshoot. Thank you for all your help - I assume I’ll be back as I continue to use FreeRTOS.

Ray

rtel wrote on Friday, March 13, 2015:

That’s great - I would appreciate you uploading the project to the
FreeRTOS Interactive site http://interactive.freertos.org

Regards.

gmgrpl wrote on Saturday, March 14, 2015:

Here is my project zipped up - according to my reading on http://interactive.freertos.org I’m supposed to post it on the forum. If I’ve violated a rule, please excuse me, I’m still new to the forum.

Project Parameters:

  1. Target - TI RM46L852ZWT Hercules microcontroller HDK,
  2. Code generation - HALCoGen v0.4.03,
  3. IDE - Code Composer Studio version 6.1.0.00104,
  4. Compiler - TI v5.2.3

When I generated code with HALCoGen, I deleted their “os_heap.c” file and replaced it with FreeRTOS+UDP “heap_4.c”

This is a simple implementation - it is not a zero copy implementation.

I did not “tune” or otherwise optimize the task stack sizes or heap size.

The purpose of the LED blinky tasks is to convince myself that I could run multiple tasks cooperating with each other while running the UDP/IP stack simultaneously

The biggest issue I ran into was that I had to ‘OR’ in the “portPRIVILEGE_BIT” with the task priorities to get everything working correctly with the ARM MPU

I hope you find this useful

Ray

gmgrpl wrote on Saturday, March 14, 2015:

I forgot to mention that I used Wireshark to get the RM46’s IP address since it is configured to use DHCP.

Ray