TI Tiva TM4c1294 FreeRTOS v10.2.1

Hello,

I am looking to run the freeRTOS kernel on a tm4c1294 custom board. I am using CCS v9.1 and FreeRTOS v10.2.1. Most of the examples for this processor are older. Running kernel v7. I believe I successfully setup my project to use the newer kernel. Tick seems to be hitting and the scheduler runs.

However, any task create sends me to a fault_isr. The function prvAddNewTaskToReadyList within task.c never returns and sends me to a hardfault.

Due to the many updates to the kernel from the available projects from TI, I am using the generic config header. I am wondering if I don’t have something in there setup quite right.

Is anyone aware of a more recent example for the TI Tiva TM4C line? Anyone have an example header I could look at?

Thanks in advance!

You should find the kernel is just a drop in replacement for the v7 code - one slight difference might be that mutexes cannot be used from interrupts any more due to the way priority inheritance works. If there are any differences it will be with the tools, rather than the C code.

Are you saying creating a task after the scheduler has already started is causing the hard fault? It sounds like it because you say the tick interrupt is running. If that is the case then creating a task is not the issue in itself as you will already have created at least the idle task with an issue. Therefore your problem might be that you are simply running our of heap, or something like that.

When you step into the code in the debugger, at which point does it crash?
Are you sure it is crashing in the task create function, and not in the task you are creating - as that task may execute before the task create function exits.
Have you done everything recommended here?

Hi Richard,

I was not familiar with the link you provided. I’ll look those over.

I should have been more clear in my initial post. If I comment out all task creations then the scheduler is able to launch,hit the systick interrupt, and is not hitting the faultisr. Adding any task creation in creates the problem.

The line of code that sends it out to lunch is with tasks.c. It has the comment “Fill the stack with a known value to assist debugging.” This seems true for any task created. I have toyed with the stacksize bigger and smaller.

I will be reviewing the links you have given.

That line fills the stack allocated to the task with a known value. If writing to the task stack causes a hard fault then it might be that the memory is invalid or overlapping with other memory. Which heap allocation scheme are you using? Are you sure your linker script is correct?

Agreed. I have taken a look at the linker file. I was using the default linker tables but I have also tried re-arranging them. That doesn’t seem to make a difference.

I am currently trying to use Heap_1.c but I have also tried heap_4.c with similar results.

In my latest attempt I am passing in memset(0x20008000, 0xa5u, (512 * 4)).

Hi all,

I’m trying to make a simple demo work with a similar MCU.
I’m using the TIVA Launchpad (that runs on TM4C123).
I’m using TI CCS (V 10.0.0.00010) and TI compiler (v20.2.1.LTS) with the last FreeRTOS version (10.3.1).
The project compiles without warnings.
The main program is very simple, it creates a task and start the scheduler.
I read the FAQ and I’m reading the book too.
The issue I have is similar to the one Jeff reported.

As soon as the vTaskStartScheduler() starts the PC jumps to the Default_Handler. I stepped into the code and I found that this happens when the function vPortStartFirstTask() is invoked.
The first time that I run the program, the PC jumps (as wrote above) to the Default_Handler, but if I just Restart the debug it finishes into the HardFault_Handler and if I restart again (third time and more) the PC finishes to the instruction svc #0 (last one here):

	.align 4
vPortStartFirstTask: .asmfunc
	;/* Use the NVIC offset register to locate the stack. */
	ldr r0, NVICOffsetConst
	ldr r0, [r0]
	ldr r0, [r0]
	;/* Set the msp back to the start of the stack. */
	msr msp, r0
	;/* Clear the bit that indicates the FPU is in use in case the FPU was used
	;before the scheduler was started - which would otherwise result in the
	;unnecessary leaving of space in the SVC stack for lazy saving of FPU
	;registers. */
	mov r0, #0
	msr control, r0
	;/* Call SVC to start the first task. */
	cpsie i
	cpsie f
	dsb
	isb
	svc #0
	.endasmfunc

I know these lasts are not really helpful, but there is nothing more that I can mention.
My project is the one depictd in this post and the configuration used it is basically this.
Regarding the memory management I’m using the heap_4.

I checked both the stack and the heap configuration and to me looks fine. In particular I’m using the following:

#define configMINIMAL_STACK_SIZE            ( ( uint16_t ) 100 )
#define configTOTAL_HEAP_SIZE               ( ( size_t ) ( 10 * 1024 ) )
#define configCHECK_FOR_STACK_OVERFLOW          2

I can see the SRAM filled with the pattern A5A5A5A5.
So, to understand which is the exception that triggers the Default_Handler I found very helpful this page although I couldn’t run the code contained in the section Determining Which Exception Handler is Executing. Is there someone that can help me to translate this for the compiler I use? I tried using the __asm"" or the asm"", but didn’t work.
I think that this would be very helpful not only for the developing phase, so I’d really like to have it.

Any other ideas?
Anyone else had this issue?

Regards,
AGA

It would have been best to start a new thread for your post, otherwise it might have gone unnoticed.

It is likely that, by default, the default handler is installed as the handler for every interrupt that can occur on your MCU. If you want to actually use an interrupt you have to replace the default handler with the real interrupt handler. Starting the scheduler on that chip uses the SVC interrupt, which is triggered by executing the svc instruction you will see at the end of the code sequence you posted. Did you install a handler for the SVC interrupt? Or is the default handler still installed for the SVN interrupt. See the answer to the first FAQ on this page https://www.freertos.org/FAQHelp.html

Hi Richard,

At the moment my task does not use any interrupts. It should just turn on a LED.
In any case I know what you mean. I normally edit my startup code adding all the interrupts handlers as weak.
Actually I define them in the startup code with with the same CMSIS names):

...
void PendSV_Handler        (void) __attribute__ ((weak, alias("Default_Handler")));
void SysTick_Handler       (void) __attribute__ ((weak, alias("Default_Handler")));
void SysTick_Handler       (void) __attribute__ ((weak, alias("Default_Handler")));
...

And of course I replaced the “default_handler” in the vector table as:

...
SVC_Handler,            /* SVCall handler                  */
DebugMon_Handler,       /* Debug monitor handler           */
0,                      /* Reserved                        */
PendSV_Handler,         /* The PendSV handler              */
SysTick_Handler,        /* The SysTick handler             */
...

I just added the following lines, as you suggested me from the FAQ page, but I still have the same issue:

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

I’m going to open a new thread :wink:
Many thanks!

Regards,
AGA

AGA,

I never posted an update. I found a work around that gets me rolling but did not give me the warm fuzzies. It was a proof of concept project so I had limited time and resources. I made it work.

Anyways, I turned on optimization for the project and poof the hard fault disappeared. It was a hail mary of a fix. I do not remember the exact level but I thought any size or speed optimization worked.

Good luck I hope you are able to get further than me. I’ll be anxiously watching your updates.

Jeff

I have seen this before where the C startup code is written in C. If it is doing something like clearing memory to zero using a loop counter that is stored on the stack then the loop counter also gets cleared to zero and you have a problem. Turning on optimisation results in the loop counter being held in a register, rather than on the stack, so the loop counter itself is not corrupted as the memory is cleared. I think some early Stellaris projects (Stellaris became Tiva) used C code to clear memory and to get it to work we turned optimisation on for just the startup C files. That was a long time ago though so my memory might not be quite correct.