Announcements

Equip yourself to optimize AURIX™ MCUs for Evs at the EV Webinar. Click here to register.

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

AURIX™ Forum Discussions

User19424
Level 3
Level 3
First solution authored First like received
Hello, I am a beginner with regard to programming embedded boards

I am trying to set a certain bit in a peripheral register (PSW) (Trying to set the Protection Register Set (PRS) to Set1)
Thing is, it crashes when I try. I must be doing something wrong and would appreciate help!

(&CPU0_PSW)->B.PRS |= (1 << 12)
// Also tried manually changing it, didn't work as well
(&CPU0_PSW) |= 0x1000


Am I accessing it the wrong way? Is there a special way to access Peripheral Registers? I tried to find an example of altering these types of registers but couldn't find any.
Thanks!
0 Likes
6 Replies
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
PSW is a CPU Core Special Function Register (CFSR) - see page 287 of tc27xD_um_v2.2.pdf. Per 5.7.1 CSFR and SFR base Locations on page 284:
A CPU must access its own CSFR registers using MTCR and MFCR instructions.

The crash you're getting is undoubtedly an Instruction Error (Trap Class 2), Invalid Memory Access (TIN 5), per page 102 of the TriCore Architecture Manual (TC_Architecture_vol1_TC161_TCS_TC16P_TC16E.pdf):

Implementation constraints which can raise the MEM trap are
• A memory address is used to access a Core SFR (CSFR) rather than using a MTCR/MFCR instruction (CSFR access)


You can verify that by seeing if you're taking the second trap vector (BTV + 0x40), and that D15=5 (Trap Identification Number=5).

So, try something like this instead (assuming you're using the Tasking compiler):

#include "IfxCpu_reg.h" // to get the CPU_PSW definition
uint32 psw;
psw = __mfcr( CPU_PSW ); // CPU_PSW is 0xFE04 from IfxCpu_reg.h
psw |= 0x1000;
__mtcr( CPU_PSW, psw );
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
UC_wrangler wrote:
PSW is a CPU Core Special Function Register (CFSR) - see page 287 of tc27xD_um_v2.2.pdf. Per 5.7.1 CSFR and SFR base Locations on page 284:

The crash you're getting is undoubtedly an Instruction Error (Trap Class 2), Invalid Memory Access (TIN 5), per page 102 of the TriCore Architecture Manual (TC_Architecture_vol1_TC161_TCS_TC16P_TC16E.pdf):

You can verify that by seeing if you're taking the second trap vector (BTV + 0x40), and that D15=5 (Trap Identification Number=5).

So, try something like this instead (assuming you're using the Tasking compiler):

#include "IfxCpu_reg.h" // to get the CPU_PSW definition
uint32 psw;
psw = __mfcr( CPU_PSW ); // CPU_PSW is 0xFE04 from IfxCpu_reg.h
psw |= 0x1000;
__mtcr( CPU_PSW, psw );


Thank you very much!
It no longer crashes and I see when debugging using TRACE32 that it does change it properly to Set1

But another issue then arises, after the functions exits (ret16 mnemonic is run) it reverts back to Set0 again.
Why Does this happen? I would like to keep it Set1.

Again thanks for taking your time.
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
When you do a CALL, the TriCore saves PSW (and other registers) into an upper context - see Figure 4-1 Upper and Lower Contexts from TriCore Architecture Manual volume 1. When you do a RET, the previous value of PSW is restored from the upper context.

So, if you want to keep PSW.PRS=1, you'll need to do it from a higher level function.

In big applications that use a commercial OS (e.g, AUTOSAR OS), configuring PSW.PRS and the MPU registers is handled by the operating system on a per-task basis.
0 Likes
User19424
Level 3
Level 3
First solution authored First like received
UC_wrangler wrote:
When you do a CALL, the TriCore saves PSW (and other registers) into an upper context - see Figure 4-1 Upper and Lower Contexts from TriCore Architecture Manual volume 1. When you do a RET, the previous value of PSW is restored from the upper context.

So, if you want to keep PSW.PRS=1, you'll need to do it from a higher level function.

In big applications that use a commercial OS (e.g, AUTOSAR OS), configuring PSW.PRS and the MPU registers is handled by the operating system on a per-task basis.



Ah I see. Makes sense. Yes my board is running AUTOSAR Classic.
So Just to see that I understood correctly, I basically have to set them in Board_start()? or in main()?

And If I am already asking, does SYSCON also behave like this? (Needed for PROTEN field). Didn't see it in the figure you referenced me to check so I am assuming that no?

Once again thank you for your professionally written responses.
0 Likes
NeMa_4793301
Level 6
Level 6
10 likes received 10 solutions authored 5 solutions authored
Here it depends on your application - if you only have one context, then setting PRS in main is appropriate. If your application requires multiple protection sets, then PRS must be set at the top level of each context.

SYSCON is also a CSFR (CPU-specific Special Function Register) - so yes, MTCR/MFCR is required to write or read it. See 5.8.8 Summary of CSFR Reset Values and Access Modes on page 315 of tc27xD_um_v2.2.pdf.
0 Likes
cwunder
Employee
Employee
25 likes received 25 solutions authored 100 sign-ins
BEC wrote:
I would like to keep it Set1.


Keep in mind, when using the CPU MPU you need to be aware that the Protection Register Set is always set to 0 on an interrupt or trap by the hardware.
0 Likes