http://renesasrulz.com/renesas_forum_home/rx/f/27/p/4785/14881.aspx
embedded techniques for everyone ; solve atleast one problem of the world a day ; provide the world what you do not get ; invent and service the world
Sunday, July 31, 2016
Sunday, March 06, 2016
Sunday, January 24, 2016
IMASK Usage
In ITRON, IMASK is used as follows:
As the interrupt mask is updated to Kernel interrupt mask level, IMASK is used to refer the mask level used by the task entity while running at user level (outside kernel processing).
While running at Task level, IMASK does not matter as it is overwritten when calling some Kernel System call. The Value at the Interrupt Mask register (NOW_SR) matters. So, when branching to Task back, no need to update the IMASK global variable, but it is necessary to update only the actually Interrupt Mask Register. Because, the IMASK is going to be updated by NOW_SR, once back to running task.
Once inside the kernel, the IMASK matters very much. Only IMASK stores the Interrupt Mask level of the System when it was at application level. So, IMASK should not be changed once the System entered Kernel. It should reflect the NOW_SR of running application.
Same way, Interrupt Status (NOW_SR) matters very much inside the Application Level.
Then, is it wrong to refer to Interrupt Status Register directly inside Return Interrupt instead of IMASK?
No. Interrupt Status (NOW_SR) must be referred directly.
Because, Interrupt occurs only in Application level. Only Interrupt Status (NOW_SR) is valid in Application Level. IMASK is NOT valid inside Application Level. So, it is correct to refer to Interrupt Status directly in ReturnInterrupt. Instead, referring to IMASK in ReturnInterrupt is wrong.
Since because, while entering the kernel through interrupt, the interrupt level of application/ISR is not saved in IMASK. So, it is wrong to refer to IMASK inside ReturnInterupt.
Where referred?
While returning from Interrupt → If IMASK is not zero, no scheduling while returning from Interrupt
(Including the System task, Timer handlers not scheduled)
In dispatch() calls where scheduling is involved, but INEST, DDISP are not checked at entrance of the system call.
In Disable Dispatch dis_dsp() → If current mask level of the task (IMASK) is not task level, return E_CTX.
Enable Dispatch () → If IMASK is not task level, return E_CTX;
(Correct here for ITRONv4 implementation, No such check)
-----
Refer Interrupt Mask Status (ref_ims) → User System Call. Just return the IMASK value.
Refer CPU lock (sns_dpn) → If IMASK is not task level, return TRUE;
Refer Dispatch lock (sns_dpn) → If IMASK is not task level, return TRUE;
Refer System Status (ref_sys) → User System Call
In ret_ims and ope_ims → To restore the IMASK value
The main dispatch function dispatches the tasks with the value in the IMASK only. IMASK value is NOT changed in ret_ims/ope_ims/dispatch, that means the running function is scheduled with current IMASK of the system (running task).
Where IMASK is reset to zero (Task level) inside kernel?
1) At system startup → Executed only once at initialization
2) In system call unl_cpu →
3) In system call chg_ims(0) →
Where Interrupt Status Register is changed inside the Application level?
Nowhere. It is changed only through changing IMASK. IMASK is assigned to BASEPRI when exiting Kernel through ret_ims or dispatch.
What are the requirements in concise?
1) Immediately after entering kernel (at the next instruction of interrupt disable), the Interrupt Status Register and IMASK should be same.
2) Immediately after exiting the kernel (at the next instruction of return from system call), the Interrupt Status Register and IMASK should be same.
To continue with thought process... Apart from the Application Interrupt level and Kernel Interrupt level, there is another Important Interrupt Level which needs to be tracked and applied across Interrupt Service Routines. For example, when an interrupt occurred the interrupt level of the interrupt needs to be maintained across the ISR of that particular interrupt. And, when another nested interrupt occurs, the previous one needs to be saved and new interrupt level needs to be maintained. If interrupt controller helps on this, it would be great. In case of Cortex-M, the NVIC takes care of all this.
Subscribe to:
Posts (Atom)