Crash after restore_context

Hello, I’m working with the Renesas RL78 F14 and using interrupts from the ADC, SPI, and I2C. For the interrupts, I’m using an API with “fromISR”. Recently, I added two additional tasks that don’t directly connect with interrupts, but process data collected by the serial interfaces. However, the firmware starts crashing after the first call to portRESTORE_CONTEXT. Does anyone have any ideas where I should be looking for the problem?

Hard without the code. The app is running without the additional tasks ?
Are all tasks created properly ?
Did you define configASSERT and enabled stack checking ?

Yeah, I know that this is difficult without code. But there are two reasons I can’t share the full code. The second one is that I only wanted to ask for some prompts to be able to share the critical part. Generally, yes, it works without additional tasks. All of the tasks are generated in that way

void i2cTransmitterTask_create(void)
	TaskHandle_t handle=NULL;
	BaseType_t status=xTaskCreate(i2cTransmitterTask, "i2cTask",
			2048, NULL, 4, &handle);
	configASSERT(status == pdPASS);
	configASSERT(handle != NULL);

After performing some clean-up, the RTOS was restarted, but after a few system ticks, a Stack Overflow occurred for one of the tasks. The issue is that no matter how big the task stack is, the overflow still occurs. Additionally, I placed a breakpoint at the beginning of the task and observed that the overflow occurs before the task starts processing.

So the only interrupt is from the timer. Rest of interfaces are configured at the begining of tasks.

That’s really weird… for me it seems that either the heap used by FreeRTOS (to allocate stack and TCB of tasks) has a problem or something is wrong with the port you’re using.
If data already gets corrupted with just the systick running, something fundamental seems to be wrong or broken. Given that the hardware is ok. Do you use MCU internal RAM ?
To be sure, things were fine without the 2 additional tasks created ?

I tested it on two boards, and the symptoms were the same. The RAM is internal, and the microcontroller is R5F10PGJ. I need to carefully read the datasheet of the microcontroller to find more information. I found out that at the beginning of the RAM, there is a common area for the debugger. Therefore, I set the appropriate offset in the linker.

I couldn’t find a specific FreeRTOS demo for this microcontroller family using GCC, so I used the one from the G13 family and adapted some parts.

Hmm … there is a port:

for your MCU and toolchain.
I’d use the original :wink:

Yes, but in that case, the register exists in g13/14 instead of f13/14 like in my case. Generally, I use this register, but I had to add my implementation of the timer because it was not included in this repository.

I mean when I talking about adoptet some parts that i change only Timer register to correct for my Uc.

I see during debugging that when stack is on specific area then something is stuck.

Could you add some more details ? What means stuck ? Does the call stack provide some more hints ?

Okay, it was a misunderstanding on my part. Now I think that this is mostly related to GCC rather than FreeRTOS (I guess). On the call stack, I see that there is an address of 0xff8c28, but in fact, the address of the beginning task is 0x8c28. When I reduce the size of the firmware by removing some tasks, the call stack and address for this task match

In my experience compiler bugs are extremely rare.
Are you sure it’s not an programming error ? Do you have enabled the debugging tools mentioned (assert/stack checks) ? Is the linker script ok ? Is the non-optimized DEBUG build crashing or do you use the optimizer ?

I find something in Port.c

StackType_t *pxPortInitialiseStack

*pulLocal = ( ( ( uint32_t ) pxCode ) | ( portPSW << 24UL ) );

portPSW is 0xC6
Ones time (when everything going well) in memory is 0xC6007B31 (pxCode=0x7b31)

next time after added some task result in memory is 0xFFFF8C28 (pxCode=0x8c28)

even i tried to hardcode 0xc6000000 with no result… I dont know what is wrong here.

next task the same code

everything is ok

I added extra variable tempGowno (gowno in Polish means shit)
I was without hope that it could be able to help. But in fact it working.

After casting to uint32, there may have been something in memory, so I added an extra variable to ensure that after the ‘OR’ operation, the bytes that should be zero remain zero. However, I am curious as to why I did not encounter this problem before.

Your solution absolutely makes sense :+1: (without knowing the RL78 port in detail)

1 Like