Interarrival Time Protection (AURIX)

Forum related to ERIKA Enterprise and RT-Druid version 2

Moderator: paolo.gai

AlTi

Interarrival Time Protection (AURIX)

Post by AlTi »

Hi,

I have two Tasks in my configuration which are activated by Alarms in a cylce of 10ms. Timing Protection is activated for both Tasks (Timeframe = 9ms) and the Tasks shouldn´t interrupt each other as they are activated at different times.
When I´m running the program, at some time the interarrival protection for TaskMasterA triggers an error. The question is why? I suspect it has something to do with the overflow of the SystemTimer which leads to an early activation of TaskMasterA. Maybe do I have to align MAXALLOWEDVALUE in COUNTER to the cycle?

Here´s the configuration:

Code: Select all

	TASK TaskMasterA {
		CPU_ID = "master";
		PRIORITY = 2;
		AUTOSTART = FALSE;
		STACK = PRIVATE {
			SYS_SIZE = 512;
		};
		ACTIVATION = 1;
		SCHEDULE = FULL;
		EVENT = Event1;

		TIMING_PROTECTION = TRUE {
			EXECUTIONBUDGET = 0.001;
			TIMEFRAME = 0.009; // <= 10ms
		};
	};

	TASK TaskMasterB {
		CPU_ID = "master";
		PRIORITY = 1;
		AUTOSTART = FALSE;
		STACK = PRIVATE {
			SYS_SIZE = 512;
		};
		ACTIVATION = 1;
		SCHEDULE = FULL;

		TIMING_PROTECTION = TRUE {
			EXECUTIONBUDGET = 0.005; 
			TIMEFRAME = 0.009;
		};
	};

	ALARM Alarm1 { 
		COUNTER = SystemTimer;
		ACTION = ACTIVATETASK{
			TASK = TaskMasterA;
		};
		AUTOSTART = TRUE {
			ALARMTIME = 1;
			CYCLETIME = 10;
		};
	};

	ALARM Alarm2 { 
		COUNTER = SystemTimer;
		ACTION = ACTIVATETASK{
			TASK = TaskMasterB;
		};
		AUTOSTART = TRUE {			
			ALARMTIME = 5;
			CYCLETIME = 10;
		};
	};

	COUNTER SystemTimer { 
		CPU_ID = "master";
		MINCYCLE = 1;
		MAXALLOWEDVALUE = 2147483647;	
		TICKSPERBASE = 1;
		TYPE = HARDWARE {
			DEVICE = "STM_SR0";
			SYSTEM_TIMER = TRUE;
			PRIORITY = 2;
		};
		SECONDSPERTICK = 0.001;
	};  

e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

I tried your configuration and I don't have any problem.

As far as I cas say you have configured both timing protection: execution budgets and time interrarival frame.

Are you sure that the signaled error is E_OS_PROTECTION_ARRIVAL (17), the one tied to interrarrival, and not E_OS_PROTECTION_TIME (16), that would have mean budget expired.

Regards,
Errico
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

Thank you for testing! How long was your test running? The earliest time I got this error was after 10s and the latest error after 60s ... so I would suggest to run the test at least one minute.

I´m sure about the Interarrival-Error. Additionally, I have set a breakpoint in EE_as_tp_handle_interarrival (see the picture). Can you see something suspicious in the Locals View in the picture?

now - frame_start = 1217520; that means 6,08ms at 200MHz ... so the Protection Mechanism seems to work correctly.
Attachments
InterarrivalError.PNG
InterarrivalError.PNG (58.05 KiB) Viewed 16167 times
e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

Looking deeper at the configuration I can figure out what's going on.

The problem it's the Event, when a TASK start a waiting it start a interarrival frame too (Read AUTOSAR specicification, I know you can do that ^^), so you have to assure that that the SetEvent came after 9 ms.
AUTOSAR OS prevents timing errors from (3) by using inter-arrival time protection to
guarantee a statically configured lower bound, called the Time Frame, on the time
between:
A task being permitted to transition into the READY state due to:
[*]o Activation (the transition from the SUSPENDED to the READY state)[/*]
[*]o Release (the transition from the WAITING to the READY state)[/*]

A Category 2 ISR arriving

An arrival occurs when the Category 2 ISR is recognized by the OS
Inter-arrival time protection for basic tasks controls the time between successive
activations, irrespective of whether activations are queued or not. In the case of
queued activations, activating a basic task which is in the READY or RUNNING state is
a new activation because it represents the activation of a new instance of the task.
Inter-arrival time protection therefore interacts with queued activation to control the
rate at which the queue is filled.
Inter-arrival time protection for extended tasks controls the time between successive
activations and releases. When a task is in the WAITING state and multiple events are
set with a single call to SetEvent() this represents a single release. When a task
waits for one or more events which are already set this represents a notional
Wait/Release/Start transition and therefore is considered as a new release.
Errico
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

Sorry Errico, I haven´t mentioned that I am not using this Event inside the Task. Actually I have deleted all code inside the Task (except TerminateTask()) for testing. To sum the configuration up, the sequence on Core0 should be:

0ms -> Alarm1 activates TaskMasterA
1ms -> TaskMasterA must be finished (execution budget = 1ms)
2ms
3ms
4ms -> Alarm2 activates TaskMasterB
5ms
6ms
7ms
8ms
9ms -> TaskMasterB must be finished (execution budget = 5ms)
10ms -> Alarm1 activates TaskMasterA
etc.

Since you have tested this scenario without problems, can you copypaste the whole oil-file? Maybe I can find a difference that is causing this problem.
e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

Hi,

I could replicate the problem seems tied to the driver of system timer that in some particular situation can raise more interrupts than you would expect (Infineon STM perpherial it is really complicated to be easiest timer that they have ^^).

Could you please test this patch too in your environment:

Code: Select all

diff --git a/pkg/mcu/infineon_common_tc2Yx/src/ee_tc2Yx_system.c b/pkg/mcu/infineon_common_tc2Yx/src/ee_tc2Yx_system.c
index 47f5690..59cf347 100644
--- a/pkg/mcu/infineon_common_tc2Yx/src/ee_tc2Yx_system.c
+++ b/pkg/mcu/infineon_common_tc2Yx/src/ee_tc2Yx_system.c
@@ -269,27 +269,27 @@ EE_STM_SR0_STORAGE void EE_tc2Yx_stm_set_sr0(EE_UINT32 usec,
 {
   EE_UREG compare_value;
 
-  EE_UREG size_of_compare;
+  /* EE_UREG size_of_compare; */
 
   /* I need to make this setup atomic */
   /* USING SUSPEND/RESUME IRQ WOULD BE BETTER (code executable even with isr
      disabled) BUT IS NOT COMPATIBLE WITH NOT-TRUSTED USER-1 PROFILE */
   /* EE_FREG flags = EE_tc_suspendIRQ(); */
-    EE_tc_disableIRQ();
+  EE_tc_disableIRQ();
 
   /*  Evaluate next compare value (actual value + increment,
       I don't need to handle wrap around) */
   compare_value = EE_tc2Yx_stm_us_ticks(usec) +
     EE_tc2Yx_stm_get_time_lower_word();
   /* Adjust the size of the mask */
-  size_of_compare = 31U - EE_tc_clz(compare_value);
+  /* size_of_compare = 31U - EE_tc_clz(compare_value); */
 
   /* Set Compare Value Register */
   EE_STM_CMP0.U = compare_value;
 
-  if(intvec != (EE_TYPEISR2PRIO)EE_ISR_UNMASKED) {
+  if ( intvec != (EE_TYPEISR2PRIO)EE_ISR_UNMASKED ) {
     EE_STM_CMCON.B.MSTART0 = 0U;
-    EE_STM_CMCON.B.MSIZE0  = (EE_UINT8)size_of_compare;
+    EE_STM_CMCON.B.MSIZE0  = 31U; /* (EE_UINT8)size_of_compare; */
     /* Tie STM Service Request 0 with Compare Register 0 */
     EE_STM_ICR.B.CMP0OS = 0U;
     /* Enable STM Service Request Source */
@@ -314,26 +314,14 @@ EE_STM_SR0_STORAGE void EE_tc2Yx_stm_set_sr0(EE_UINT32 usec,
 
 EE_STM_SR0_STORAGE void EE_tc2Yx_stm_set_sr0_next_match(EE_UINT32 usec)
 {
-  EE_UREG compare_value;
-
-  EE_UREG size_of_compare;
-
   /* I need to make this setup atomic */
   /* USING SUSPEND/RESUME IRQ WOULD BE BETTER (code executable even with isr
      disabled) BUT IS NOT COMPATIBLE WITH NOT-TRUSTED USER-1 PROFILE */
   /* EE_FREG flags = EE_tc_suspendIRQ(); */
-    EE_tc_disableIRQ();
+  EE_tc_disableIRQ();
   /* Evaluate next compare value (previous one + increment,
      I don't need to handle wrap around) */
-  compare_value = EE_tc2Yx_stm_us_ticks(usec) +
-    EE_tc2Yx_stm_get_time_lower_word();
-  /* Adjust the size of the mask */
-  size_of_compare = 31U - EE_tc_clz(compare_value);
-
-  /* Set Compare Value Register */
-  EE_STM_CMP0.U = compare_value;
-  /* Set Compare Size Value Register */
-  EE_STM_CMCON.B.MSIZE0 = (EE_UINT8)size_of_compare;
+  EE_STM_CMP0.U += EE_tc2Yx_stm_us_ticks(usec);
 
   /* EE_tc_resumeIRQ(flags); */
   EE_tc_enableIRQ();
@@ -344,7 +332,7 @@ EE_STM_SR1_STORAGE void EE_tc2Yx_stm_set_sr1(EE_UINT32 usec,
 {
   EE_UREG compare_value;
 
-  EE_UREG size_of_compare;
+  /* EE_UREG size_of_compare; */
 
   /* I need to make this setup atomic */
   /* USING SUSPEND/RESUME IRQ WOULD BE BETTER (code executable even with isr
@@ -356,14 +344,14 @@ EE_STM_SR1_STORAGE void EE_tc2Yx_stm_set_sr1(EE_UINT32 usec,
   compare_value = EE_tc2Yx_stm_us_ticks(usec) +
     EE_tc2Yx_stm_get_time_lower_word();
   /* Adjust the size of the mask */
-  size_of_compare = 31U - EE_tc_clz(compare_value);
+  /* size_of_compare = 31U - EE_tc_clz(compare_value); */
 
   /* Set Compare Value Register */
   EE_STM_CMP1.U = compare_value;
 
-  if(intvec != (EE_TYPEISR2PRIO)EE_ISR_UNMASKED) {
+  if ( intvec != (EE_TYPEISR2PRIO)EE_ISR_UNMASKED ) {
     EE_STM_CMCON.B.MSTART1 = 0U;
-    EE_STM_CMCON.B.MSIZE1  = (EE_UINT8)size_of_compare;
+    EE_STM_CMCON.B.MSIZE1  = 31U; /* (EE_UINT8)size_of_compare; */
     /* Tie STM Service Request 1 with Compare Register 1 */
     EE_STM_ICR.B.CMP1OS = 1U;
     /* Enable STM Service Request Source */
@@ -387,10 +375,6 @@ EE_STM_SR1_STORAGE void EE_tc2Yx_stm_set_sr1(EE_UINT32 usec,
 
 EE_STM_SR1_STORAGE void EE_tc2Yx_stm_set_sr1_next_match(EE_UINT32 usec)
 {
-  EE_UREG compare_value;
-
-  EE_UREG size_of_compare;
-
   /* I need to make this setup atomic */
   /* USING SUSPEND/RESUME IRQ WOULD BE BETTER (code executable even with isr
      disabled) BUT IS NOT COMPATIBLE WITH NOT-TRUSTED USER-1 PROFILE */
@@ -398,16 +382,8 @@ EE_STM_SR1_STORAGE void EE_tc2Yx_stm_set_sr1_next_match(EE_UINT32 usec)
   EE_tc_disableIRQ();
   /* Evaluate next compare value (previous one + increment,
      I don't need to handle wrap around) */
-  compare_value = EE_tc2Yx_stm_us_ticks(usec) +
-    EE_tc2Yx_stm_get_time_lower_word();
-  /* Adjust the size of the mask */
-  size_of_compare = 31U - EE_tc_clz(compare_value);
-
-  /* Set Compare Value Register */
-  EE_STM_CMP1.U = compare_value;
+  EE_STM_CMP1.U += EE_tc2Yx_stm_us_ticks(usec);
 
-  /* Set Compare Size Value Register */
-  EE_STM_CMCON.B.MSIZE1 = (EE_UINT8)size_of_compare;
   /* EE_tc_resumeIRQ(flags); */
   EE_tc_enableIRQ();
 }
Thank in advance for your feedback,

Errico
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

I couldn´t apply the patch with git "git apply patch" - got an error "fatal: corrupt patch at line 6", therefore I manually patched the file. I have tested it and didn´t get an error so far.
Now, I think I understand the problem, too: Example with 4Bit Counter:

Current Counter-Value = b0111
"next match" = b0010 (wrap around)
MSIZE0 is set to 2.
This would lead to a match at b1010 -> Interrupt before it´s exptected.

Thank you very much for your help, Errico :)
e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

Yup,

that was exactly the problem (sorry, bug happens).

And sorry for the patch, I didn't understood how to generate patch with git yet...

I'm gonna to commit on the repository, but to use the head of the repository you will need to upgrade RT-Druid with an update site (and I'm not sure if it is already availabe), so I would suggest you to keep your version locally patched.

See you.
Errico
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

No problem, thank you for the patch :)

I have noticed this interesting requirement recently:
[OS565] ⌈ When CallTrustedFunction() is called and the caller of
CallTrustedFunction() is supervised with timing protection, the Operating
System shall delay any timing protection errors until the return of
CallTrustedFunction(). ⌋
Is this requirement implemented in ERIKA? I placed an endless loop into my trusted function and then I called the trusted function from a task with timing protection enabled (execution budget). I expected that the error would be delayed forever, but the ProtectionHook was called with error 16 after some seconds.
e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

Yes the requirement should be supported, and If the exception really happens after seconds the problem can be only in the return from a Interarrival frame recollection procedure, that's the only event that has that periodicity.

Interarrival frame recollection it's tied to a core exception (shared with timing budgets) and has it's own execution path, where probably I forgot to check if I'm inside a TrustedFunction, before reeanibling the timing budget.

Errico
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

Update:
Yesterday, after I wrote this post, I completly recompiled the project and then I got this error immediatly. The trap bus handler (EE_tc_bus_handler) was called (with TAE, TIN7) and later the ProtectionHook. Maybe there´s something in this path.
e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

Try this and let me know.

I'm still using git diff to create the patch because I don't want commit (even locally), if I'm not sure that everything is working.

Bye

Code: Select all

diff --git a/pkg/kernel/as/src/ee_as_mem_prot.c b/pkg/kernel/as/src/ee_as_mem_prot.c
index 92397c4..d82bdee 100644
--- a/pkg/kernel/as/src/ee_as_mem_prot.c
+++ b/pkg/kernel/as/src/ee_as_mem_prot.c
@@ -299,6 +299,30 @@ StatusType EE_as_CallTrustedFunction(TrustedFunctionIndexType FunctionIndex,
      be handled by the syscall handler, but TP have to be handled here... */
   register EE_as_Application_RAM_type * const app_RAM_ptr =
     &EE_as_Application_RAM[EE_as_active_app];
+
+  /*  Reaction to timing protection can be defined to terminate the
+      OSApplication. If a task is inside CallTrustedFunction() and task
+      rescheduling takes place within the same OSApplication, the newly running
+      higher priority task may cause timing protection and terminate the
+      OSApplication, thus indirectly aborting the trusted function.
+      To avoid this, the scheduling of other Tasks which belong to the same
+      OS-Application as the caller needs to be restricted, as well as the
+      availability of interrupts of the same OS-Application. */
+  /* [SWS_Os_00565]: When CallTrustedFunction() is called and the caller of
+      CallTrustedFunction() is supervised with timing protection, the Operating
+      System shall delay any timing protection errors until the return of
+      CallTrustedFunction(). */
+  /* [SWS_Os_00564]: If such a violation is detected inside a nested call
+      sequence of CallTrustedFunction() of a task, the delay shall last until
+      the return of the last CallTrustedFunction(). */
+  /* The following handle enventual TP errors. The check if we are inside a
+     Trusted Function Call inside, because the following function is called at
+     the end of all ERIKA Services, and the check have to be done at every
+     service's call */
+
+  /* Primitive Lock Procedure */
+  EE_OS_DECLARE_AND_ENTER_CRITICAL_SECTION();
+
   EE_ORTI_set_service_in(EE_SERVICETRACE_CALLTRUSTEDFUNCTION);
 
 #ifdef EE_SERVICE_PROTECTION__
@@ -357,37 +381,20 @@ StatusType EE_as_CallTrustedFunction(TrustedFunctionIndexType FunctionIndex,
   }
 
   if ( ev != E_OK ) {
+#ifdef __OO_HAS_ERRORHOOK__
     EE_OS_PARAM(os_function_index);
     EE_OS_PARAM(os_function_params);
     EE_OS_PARAM_VALUE(os_function_index, FunctionIndex);
     EE_OS_PARAM_REF(os_function_params, trusted_function_parameter_ref,
       FunctionParams);
+#endif /* __OO_HAS_ERRORHOOK__ */
     EE_os_notify_error(OSServiceId_CallTrustedFunction, os_function_index,
       os_function_params, EE_OS_INVALID_PARAM, ev);
   }
 
-  /*  Reaction to timing protection can be defined to terminate the
-      OSApplication. If a task is inside CallTrustedFunction() and task
-      rescheduling takes place within the same OSApplication, the newly running
-      higher priority task may cause timing protection and terminate the
-      OSApplication, thus indirectly aborting the trusted function.
-      To avoid this, the scheduling of other Tasks which belong to the same
-      OS-Application as the caller needs to be restricted, as well as the
-      availability of interrupts of the same OS-Application. */
-  /* [SWS_Os_00565]: When CallTrustedFunction() is called and the caller of
-      CallTrustedFunction() is supervised with timing protection, the Operating
-      System shall delay any timing protection errors until the return of
-      CallTrustedFunction(). */
-  /* [SWS_Os_00564]: If such a violation is detected inside a nested call
-      sequence of CallTrustedFunction() of a task, the delay shall last until
-      the return of the last CallTrustedFunction(). */
-  /* The following handle enventual TP errors. The check if we are inside a
-     Trusted Function Call inside, because the following function is called at
-     the end of all ERIKA Services, and the check have to be done at every
-     service's call */
-  EE_as_tp_active_update_budgets_and_restart();
-
   EE_ORTI_set_service_out(EE_SERVICETRACE_CALLTRUSTEDFUNCTION);
+  EE_OS_EXIT_CRITICAL_SECTION();
+
   return ev;
 }
 #endif /* EE_SYSCALL_NR > EE_MAX_SYS_SERVICEID */
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

Can you upload the patch please (or ee_as_mem_prot.c)? I get "corrupt patch at line 34" now. Maybe there is something wrong with the format.
e.guidieri

Re: Interarrival Time Protection (AURIX)

Post by e.guidieri »

OK, we try this way.

I had to rename .zip the file because some forum policies, but actually is a .c file
Attachments
ee_as_mem_prot.zip
(14.91 KiB) Downloaded 511 times
AlTi

Re: Interarrival Time Protection (AURIX)

Post by AlTi »

Ok, I tried the patch. I placed a loop inside the trusted function which consumes a lot of time. During the execution of the trusted function I don´t get an error, but afterwards ProtectionHook isn´t called. Should I upload a minimum example for testing?

Btw: Debugging with enabled Timing Protection is very difficult for me - it seems that the TPS-Timer continues running after a halt.
Locked