Custom Trap Classes in Aurix TC2x7

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User19424
Level 3
Level 3
First solution authored First like received
Hello,

I want to customize a Trap Class so that instead of the default infinite looping that happens, my written handling code will be run instead, after which the program will return to it's state before the Trap.
Specifically Trap Class 1, The Internal Protection Traps (Caused when PROTEN is enabled and a r/w/x violation occurs).

I tried to read the TriCore Architecture Manual's 6th chapter but had a hard time understanding what I need to do, and couldn't really find any examples of custom traps
(Has something to do with the BTV register, but I couldn't understand how to align it with the functions I want to be run during a trap)

Also on a related note, I read that the upper context is saved somehow when a trap occurs. This means I can restore the program to it's state before the trap, right? Does it happen automatically once I return from the trap?
Including states such as the SYSCON.PROTEN state?

This is my first time writing low level code that deals with these types of behaviors so I would very appreciate any type of help.
Thank you very much!
0 Likes
10 Replies
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
Hi BEC. Each compiler has its own magic way of declaring a trap handler. If you're using AURIX Development Studio and/or the iLLD, check out IfxCpu_Trap.c (in the folder Libraries/iLLD/TC27x/Tricore/Cpu/Trap). You can modify those functions to add your own behavior, That's a lot easier than figuring out how to manage the compiler and linker syntax on your own.

Take care not to remove the __asm statements at the end that restore the lower context (rslcx) and return from exception (rfe). As described in the Architecture manual, RFE will restore the upper context. Note that SYSCON is not part of upper contexts or lower contexts - see Figure 4-1 Upper and Lower Contexts on page 64.
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
Hi. Thanks for the answer!

I am using the Tasking Tricore Compiler. So am I supposed to just alter the IfxCpu_Trap.c function and add my logic? Between the __debug() and rfe? And rclx needs to be added manually, since I don't see the instruction: (?)


void IfxCpu_Trap_internalProtectionError(uint32 tin)
{
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_internalProtection, tin);
IFX_CFG_CPU_TRAP_TSR_HOOK(trapWatch);
__debug();
__asm("rfe");
}


And regarding the SYSCON, Being that it is not part of the upper/lower context, this means that if I had previously set PROTEN to 1 during startup, I don't need to worry about any resets to 0 occurring right? Because I need it enabled at all time during my program.
(except during traps but there I can just turn it on and off as I wish)

Again many thanks and have a pleasant week.
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
So am I supposed to just alter the IfxCpu_Trap.c function and add my logic? Between the __debug() and rfe?

Yes, that's right. The DEBUG instruction is ignored when there isn't a debugger hooked up (see 12.2.2 Debug Instruction in the Architecture manual.

And rclx needs to be added manually, since I don't see the instruction: (?)

I'm not sure what version of iLLD you've got, but 1.0.1.11.0 uses svlcx in the initial trap handler code, so it requires rclx before it returns:


#define IfxCpu_Tsr_CallTSR(serviceRoutine) \
{ \
__ALIGN_TRAP_TAB__; \
__asm("svlcx\n\tmov\td4,d15\n\tji\t%0\n" : : "a" (serviceRoutine) : "d4", "d15"); \
}

If your older iLLD doesn't already use svlcx/rclx, then depending on what code you add, you might or might not need to save the upper context (i.e., it depends on whether the compiler starts using D8..D15 or A12..A15).
If the upper context save/restore is needed, you could drop it in like this:
void IfxCpu_Trap_internalProtectionError(uint32 tin)
{
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_internalProtection, tin);
IFX_CFG_CPU_TRAP_TSR_HOOK(trapWatch);
__debug();
__asm("svlcx"); // Save upper context
// YOUR NEW TRAP HANDLER CODE HERE
__asm("rclx"); // Restore upper context
__asm("rfe");
}



And regarding the SYSCON, Being that it is not part of the upper/lower context, this means that if I had previously set PROTEN to 1 during startup, I don't need to worry about any resets to 0 occurring right? Because I need it enabled at all time during my program.
(except during traps but there I can just turn it on and off as I wish)

Correct.
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
UC_wrangler wrote:
Yes, that's right. The DEBUG instruction is ignored when there isn't a debugger hooked up (see 12.2.2 Debug Instruction in the Architecture manual.


I'm not sure what version of iLLD you've got, but 1.0.1.11.0 uses svlcx in the initial trap handler code, so it requires rclx before it returns:


#define IfxCpu_Tsr_CallTSR(serviceRoutine) \
{ \
__ALIGN_TRAP_TAB__; \
__asm("svlcx\n\tmov\td4,d15\n\tji\t%0\n" : : "a" (serviceRoutine) : "d4", "d15"); \
}

If your older iLLD doesn't already use svlcx/rclx, then depending on what code you add, you might or might not need to save the upper context (i.e., it depends on whether the compiler starts using D8..D15 or A12..A15).
If the upper context save/restore is needed, you could drop it in like this:
void IfxCpu_Trap_internalProtectionError(uint32 tin)
{
trapWatch = IfxCpu_Trap_extractTrapInfo(IfxCpu_Trap_Class_internalProtection, tin);
IFX_CFG_CPU_TRAP_TSR_HOOK(trapWatch);
__debug();
__asm("svlcx"); // Save upper context
// YOUR NEW TRAP HANDLER CODE HERE
__asm("rclx"); // Restore upper context
__asm("rfe");
}




Correct.


I tried the solution but it doesn't work. The Trap still behaves as it did before:
4249.attach
It also didn't seem to compile my new IfxCpu_Trap for some reason. Not sure though that I am supposed to actually see it compile.
Now, I did try and test this by adding an #include "mcals/Cpu/Trap/IfxCpu_Trap.h" into my main code, but this just unloaded a huge heap of weird errors unrelated to anything (and that didn't bother my program before which is kind of weird)
4250.attach

Why does this behave this way?
And is there any alternative way to control traps? like __trap() or something? I am using the Tasking Tricore compiler. Seems like any alteration of IfxCpu_Trap just causes more issues or doesn't do anything at all.
I'll add that the only changes I even made in IfxCpu_Trap are inside void IfxCpu_Trap_internalProtectionError(uint32 tin);
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
If you're using retail Tasking, it might depend on how you created your project.
If you're using the LSL from the iLLD, the trap handlers should be the ones in IfxCpu_Trap.c.
If you're using the LSL that Tasking generates by default, BTV will be pointing to Tasking's default trap handlers.

You can override the default handlers by referring to this section of the Tasking CTC User Guide:

1.11.4.2. Defining a Trap Service Routine: __trap(), __trap_fast()
The definition of a trap service routine is similar to the definition of an interrupt service routine. Trap functions cannot accept arguments and do not return anything:

void __trap( class ) [__vector_table(nr,...)]
tsr( void )
{
...
}

In other words, as a small example:

void __trap( 1 ) TrapHandler_InternalProtection( void )
{
__asm("svlcx"); // Save upper context
// YOUR NEW TRAP HANDLER CODE HERE
__asm("rclx"); // Restore upper context
}
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
UC_wrangler wrote:
If you're using retail Tasking, it might depend on how you created your project.
If you're using the LSL from the iLLD, the trap handlers should be the ones in IfxCpu_Trap.c.
If you're using the LSL that Tasking generates by default, BTV will be pointing to Tasking's default trap handlers.

You can override the default handlers by referring to this section of the Tasking CTC User Guide:

In other words, as a small example:

void __trap( 1 ) TrapHandler_InternalProtection( void )
{
__asm("svlcx"); // Save upper context
// YOUR NEW TRAP HANDLER CODE HERE
__asm("rclx"); // Restore upper context
}




Once again thanks for the answer but this still doesn't work.
The trap still jumps to here (screen-cap taken one step after the isync mnemonic that activated PROTEN):
4251.attach

This is my code (For now, I am just trying to get the address where the trap occurred and save it) but it is never gotten to

void __trap( 1 ) TrapHandler_InternalProtection( void )
{
__asm("svlcx"); // Save upper context
int temp_addr = __mfcr(CPU_A11); // Retrieval of the trap-causing address
address_to_section(temp_addr); // Function related to my code
__asm("rslcx"); // Restore upper context
}


Do you happen to know the reason this happens? This is unfortunately a very bothersome issue I am having.

Regarding how I made the project, It is an AUTOSAR classic project created with Tresos and compiled with Tasking compiler.
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
You'll need to track down where that OS_StartupTrap1 is. Maybe it's part of your OS? It's not part of the iLLD or of Tasking's startup code, so I'm not sure how to help here.
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
UC_wrangler wrote:
You'll need to track down where that OS_StartupTrap1 is. Maybe it's part of your OS? It's not part of the iLLD or of Tasking's startup code, so I'm not sure how to help here.


TRICORE-exceptionstartup.s according to the debugger.

I do see in the AUTOSAR files things such as TRICORE-trap1handler.c
Are there ways to override it?
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
That sounds like a great question for the OS supplier 😉

I don't know much about that, because they don't give me a free copy.
0 Likes
User22281
Level 2
Level 2
10 replies posted 10 sign-ins 5 replies posted

Hello All,

I apologize for writing in this old thread by I thought my findings could be useful to others.

I am using Tasking Tricore IDE v6.3r1 to build my project. I tried to register my own trap handler following the instructions from the Tasking CTC user guide, chapter "1.11.4.2. Defining a Trap Service Routine: __trap(), __trap_fast()". If I do that, my custom trap handler is APPENDED to the default trap handler in the trap_tab section, instead of overwriting the default handler.

The memory map file generated by the linker shows two entries in the trap vector 000:

| mpe:pflash1 | trap_tab | .text.traptab0.trapvec.000 (3471) | 0x0000000a | 0x80334100 | 0x00034100 | 0x00000002 |
| mpe:pflash1 | trap_tab | .text.traptab0.trapvec.000 (1113) | 0x0000000c | 0x8033410a | 0x0003410a | 0x00000002 |

And the resultant assembly code indeed calls first the default handler provided by Tasking, then my custom handler. If I register more handlers to the same trap, they are appended, even overwriting the next vector. I know this test is not a real use case scenario, but the linker should at least throw a warning when the code does not fit in the requested vector, instead of silently overflowing to the next vector.

Probably this is a question for the Tasking guys, but I though I could share it here, in case someone finds it useful or has run into similar issues.

0 Likes