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?
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.
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 (58.05 KiB) Viewed 16167 times
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.
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.
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:
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.
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.
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.
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.
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.
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 */
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.