Software Timers in FreeRTOS v8.2

gmgrpl wrote on Sunday, March 01, 2015:

I’m using a TI Hercules RM46x MCU
The compiler is TI v5.2.2
I’m using FreeRTOS 8.2
I have been able to execute several standard (FreeRTOS provided) demos
My question has nothing to do with a demo project

I’m trying to integrate FreeRTOS+UDP V1.0.4 into a kernel and I’m having trouble with the software timers. The UDP timer task creation call hangs and the debugger will not step into the code so that I can see what is happening. I moved the call to the timer creation to before the call to start the kernel scheduler and that worked OK. However, when stop timer is called the code execution again hangs and I cannot step into it using the debugger. When I pause the debugger, the code is executing in the interrupt assembly file.

I’m reasonably sure the issue is not with the heap space, task stack space, or the same allocations to the timer task. I’m also reasonably sure the priority of the timer task is not an issue - I set it to 2 below the top priority and I have two other tasks running at 2 below that. Any help is appreciated.

Ray

rtel wrote on Monday, March 02, 2015:

I will try and help, but don’t fully understand at what point it is going wrong.

The UDP timer task creation call hangs

Do you mean the software timer creation, rather than the timer task creation, because the time task is created by the scheduler, not FreeRTOS+UDP.

What have you set the parameters listed on the following page to?
http://www.freertos.org/Configuring-a-real-time-RTOS-application-to-use-software-timers.html

Have you called FreeRTOS_IPInit()? If so, does the problem occur inside that function, or somewhere else, and if somewhere else, where?

Regards.

gmgrpl wrote on Monday, March 02, 2015:

I call FreeRTOS_IPInit from main before I call vTaskStartScheduler. The parameters for the timer task in FreeRTOSConfig.h are:

/* Timers */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 1 )
#define configTIMER_QUEUE_LENGTH 5
#define configTIMER_TASK_STACK_DEPTH ( 512 )

I’ve experimented with the timer task settings going with low/high priorities and large stack sizes/queue lengths. Nothing seemed to help. Other relevant settings are:

#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 512 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) 131072 )

The call that is hanging is:

xARPTimer = xTimerCreate( “ARPTimer”, ( ipARP_TIMER_PERIOD_MS / portTICK_RATE_MS ), pdTRUE, ( void * ) eARPTimerEvent, vIPFunctionsTimerCallback );

inside prvIPTask. The puzzling thing is that the debugger can’t step into this call. I moved the call outside the task context and before the scheduler is called and it executes successfully. Once the scheduler is started, however, any call to a timer related function hangs in the same way: for example timer start, etc.

I successfully downloaded the TCP/IP demo for SafeRTOS targeted for the RM48 and it runs fine on my RM46 - I verified the CLI and Ethernet interfaces including DHCP, ping and telnet functionality. I looked at the SafeRTOS HALCoGen project to compare the hardware configuration and I already had everything configured properly.

Any help you can provide will be appreciated. I’m trying to get basic UDP capability working so I can prototype an application. If we go into production I plan to license SafeRTOS with the TCP/IP and CLI add-ons once we settle on a hardware platform as we need the advertised reliability. I suspect if we go into production we’ll end up with the RM57 for performance reasons. However, I’ve attempted to prototype on the RM57 and it is somewhat less mature (software wise) than the RM46.

Ray

gmgrpl wrote on Monday, March 02, 2015:

I found this code fragment in os_timer.c - it seems incorrect to me, byut maybe I’m missing something. It appears all tasks are suspended while the timer task is blocked waiting for the next time tick or a message…

		else
		{
			/* The tick count has not overflowed, and the next expire
			time has not been reached yet.  This task should therefore
			block to wait for the next expire time or a command to be
			received - whichever comes first.  The following line cannot
			be reached unless xNextExpireTime > xTimeNow, except in the
			case when the current timer list is empty. */
			vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ) );

			if( xTaskResumeAll() == pdFALSE )
			{
				/* Yield to wait for either a command to arrive, or the
				block time to expire.  If a command arrived between the
				critical section being exited and this yield then the yield
				will not cause the task to block. */
				portYIELD_WITHIN_API();
			}

What am I missing? By the way this doesn’t have anything to do with my issue.

Ray

rtel wrote on Monday, March 02, 2015:

I don’t know what os_timer.c is - this code comes from timers.c, so I
presume it is the same file, just renamed.

In the code snippet you posted, a task calling
vQueueWaitForMessageRestricted() may place the task into the Blocked
state, meaning a context switch is required so another task can be
selected to run. It is possible for a context switch to be requested
inside the xTaskResumeAll() function, but if it is not (if
xTaskResumeAll() returns pdFALSE), then one is requested directly.

Regards.

gmgrpl wrote on Monday, March 02, 2015:

I commented out the call to FreeRTOS_IPInit and everything works. The timer task was created (no timers of course) and my other tasks are running. I’m going to try to create a timer in my application and see what happens.

Ray

gmgrpl wrote on Monday, March 02, 2015:

os_timer.c is, in fact, timers.c re-named. I previously compared the files using windiff and verified that. I guess TI felt the need to rename the file for their HALCoGen support. There are several other files done the same way, but I checked them all.

Ray

gmgrpl wrote on Monday, March 02, 2015:

OK, I created a simple timer in my application code and everything works as expected. I did not put a message on the timer queue before starting the scheduler - I believe the IP stack does that.

Ray

rtel wrote on Monday, March 02, 2015:

It is perfectly ok to place messages on the timer queue before the
scheduler is started, but be aware that nothing will read them from the
queue until after the scheduler has started - so it is easy to fill the
timer queue up.

I would suggest the first thing to work out is why you can’t step into
the functions - that seems very strange and may be the route cause of
the issue.

Regards.

gmgrpl wrote on Monday, March 02, 2015:

I determined that the code hangs when the first task is started. The code hangs in os_portasm.asm at the instruction “cps #0x13”:

;/-----------------------------------------------------------/
; Start the first task by restoring its context.

    .def vPortStartFirstTask
    .asmfunc

vPortStartFirstTask
cps #0x13
portRESTORE_CONTEXT
.endasmfunc
;/-----------------------------------------------------------/

I’m stumped for right now…

Ray

rtel wrote on Monday, March 02, 2015:

I’m stumped too - but to what the code in your snippet is. I’m checking
the code in the FreeRTOS download and vPortStartFirstTask looks like
this in the asm file:

;/-----------------------------------------------------------/
; Start the first task by restoring its context.

 .def vPortStartFirstTask

vPortStartFirstTask:
portRESTORE_CONTEXT

Regards.

gmgrpl wrote on Monday, March 02, 2015:

I’m attaching my assembly file (os_portasm.asm) for your review. I assume the file was generated by HALCoGen when I created the project.

gmgrpl wrote on Tuesday, March 03, 2015:

I verified the os_portasm.asm file was generated by HALCoGen. When I imported the FreeRTOS+UDP source code, I included only those files not generated by HALCoGen. I’m using HALCoGen version v04.03.00. Do you think there might be an issue with using a newer version of HALCoGen? If so, what version do you recommend I use, and when do you think FreeRTOS+UDP will be ported to the newest version of HALCoGen?

Thanks,
Ray

rtel wrote on Tuesday, March 03, 2015:

When you generate the files - are you given any options as to the
FreeRTOS version to use? I suspect your code is trying to use the MPU,
and that might be the issue.

Have you tried swapping the files out for the version included in the
FreeRTOS download (which doesn’t use the MPU).

Regards.

gmgrpl wrote on Tuesday, March 03, 2015:

I’ve not looked in to either of those things. They are both good suggestions - I’ll investigate and get back to you with the results.

Thank you for your help,
Ray

gmgrpl wrote on Wednesday, March 04, 2015:

I had to take a break and get away for awhile. In any event, HALCoGen does not allow a FreeRTOS version selection when generating code. It does, however, allow the MPU to be enabled/disabled. I disabled the MPU and re-generated code. Unfortunately, the code in os_portasm.asm did not change and the UDP initialization process fails in the same way. This validates me creating a timer in my custom code and it running fine. I’m back to trying to figure out why the timer in the UDP stack is failing. Have you not had any of your users attempt to do the same thing I’m trying to do? Also, do you know what is done differently in the SafeRTOS demo?

Ray

rtel wrote on Wednesday, March 04, 2015:

Maybe I don’t understand what it is you are trying to do:

Unfortunately, the code in os_portasm.asm did not change

Interesting - I would have thought it would be different with and
without the MPU.

Have you not had any of your
users attempt to do the same thing I’m trying to do?

As far as I understand you are taking a working FreeRTOS project, then
building the FreeRTOS+UDP code into the project and trying to initialise
the FreeRTOS+UDP code using the published init API function. If so,
that is how you are supposed to use FreeRTOS+UDP, and I’m not sure that
anybody will have done anything different.

Also, do you
know what is done differently in the SafeRTOS demo?

Is there a SafeRTOS demo that uses FreeRTOS+UDP?

Regards.

gmgrpl wrote on Wednesday, March 04, 2015:

OK. I couldn’t come up with a good reason as to why I couldn’t create the timer in the “prvIPTask”. So I started increasing the task stack size. Low and behold when the stack size reached 16384 the timer was created and the task is running. I’m not seeing the RM46x on the network yet, so it appears I have other issues which I’ll start working on. I increased the stack sizes by powers of 2 - it would not run at 8192, and it runs OK at 16384. I didn’t experiment further to determine where the break point is. I’m new to FreeRTOS but I know there is an API for getting more information from the OS. Right now I want to get the UDP interface working. I enabled ping so I can tell when the stack is working properly. Any tips you have will be appreciated.

Ray

rtel wrote on Wednesday, March 04, 2015:

You should only need a small fraction of that stack size. Something
very strange is going on. By increasing the stack to that size I
suspect you are effectively blocking out a hole chunk of RAM that was
being used by something else, but is now not used by anything (on the
assumption the stack is allocated but most of the stack remains unused).

http://www.freertos.org/Stacks-and-stack-overflow-checking.html
http://www.freertos.org/uxTaskGetStackHighWaterMark.html

Regards.

gmgrpl wrote on Wednesday, March 04, 2015:

I jumped the gun - it wasn’t working at all. I too thought it was an outrageous amount of RAM allocated to the stacks. Maybe I need to start from the beginning. When I looked at the FreeRTOS-Plus distribution, I didn’t see a code composer studio project for the TI RM46x. I used TI’s HALCoGen and generated a project for the target. Then I took the files I found in <…\FreeRTOS\FreeRTOSV8.2.0\FreeRTOS-Plus\Source\FreeRTOS-Plus-UDP> and included them in my project. It appears most of the UDP demos are targeted for the Windows simulator. Am I going about this correctly?

Ray