Re: System Design - Need feedback from developers


Mahendravarman Rajarao (RBEI/EAA3) <Mahendravarman.Rajarao@...>
 

Hi Allan

Sorry I missed the line intrflag= 0 when typing the scenario
Please see the corrected scenario's

Scenario 1 :
=========
Int intflag = 0;

void interrupt_handler()
{
Printk ("interrupt handled \n");
------- set intrflag = 1

}

Int task1 ()
{

........interrupt initializations
........interrupt enable

While (1)
{
If (intrflag) { do something ..... ;
Intrflag=0;
} }
}


Scenario 2 :
========
Int intflag = 0;

void interrupt_handler()
{

Printk ("interrupt handled \n");
------- set intrflag = 1

}

Int task1 ()
{

........interrupt initializations
........interrupt enable

While (1)
{
Printk ("Inside while 1\n");
If (intrflag) { do something ..... ;
Intrflag=0;
}
}
}


Observations
============
In scenario 2 , if I put printk inside while 1 everything is working correctly.. Intr is generated,handled, while 1 loop inside task1 is called and intrflag is cleared and remains in while 1 loop
Until next interrupt situation occurs.

In scenario 1 , if I miss printk in while 1 loop , first interrupt is occurred, interrupt handled and the task1 while 1 is not called again ..


Best regards
Mahendravarman Rajarao

-----Original Message-----
From: Stephens, Allan [mailto:allan.stephens(a)windriver.com]
Sent: Friday, August 26, 2016 12:25 AM
To: Mahendravarman Rajarao (RBEI/EAA3) <Mahendravarman.Rajarao(a)in.bosch.com>; devel(a)lists.zephyrproject.org
Subject: RE: [devel] Re: System Design - Need feedback from developers

Mahendravarman Rajarao wrote:

-----Original Message-----
From: Mahendravarman Rajarao (RBEI/EAA3)
[mailto:Mahendravarman.Rajarao(a)in.bosch.com]
Sent: August-25-16 2:34 PM
To: Stephens, Allan; devel(a)lists.zephyrproject.org
Subject: RE: [devel] Re: System Design - Need feedback from developers

Hi Allan

Please help me to clarify the below behavior of zephyr.

Program feature:
One zephyr task named task1 and one interrupt handler.

Scenario 1 :
=========
Int intflag = 0;

void interrupt_handler()
{
Printk ("interrupt handled \n");
------- set intrflag = 1

}

Int task1 ()
{

........interrupt initializations
........interrupt enable

While (1)
{
If (intrflag) { do something }
}
}


Scenario 2 :
========
Int intflag = 0;

void interrupt_handler()
{

Printk ("interrupt handled \n");
------- set intrflag = 1

}

Int task1 ()
{

........interrupt initializations
........interrupt enable

While (1)
{
Printk ("Inside while 1\n");
If (intrflag) { do something }
}
}


Observation on scenario 1
===================
When first time interrupt occurs, the printk inside interrupt handler
is occurring and the program does not return to task1.

Observation on scenario 2
=====================
When first time interrupt occurs, the printk inside interrupt handler
is occurring and the program returns to main, prints the printk in
while loop and handles the flag If further interrupt occurs also the
program works correctly

How the printk inside the task1 helps the zephyr scheduler to schedule
the
task1 correctly in case of scenario2 ? what problem is caused in scenario 1 ?
One potential problem with your scenario 1 is that task1 is going to enter a tight loop once the first interrupt happens. That is, it's going to see the flag set, do the work, then immediately see the flag set again, do the work again, and so on. This means you're not giving the rest of the system a chance to do any work. With scenario 2 the printk done by task 1 might be providing a bit of breathing room to allow other things to happen. ... I admit that this wouldn't explain why you wouldn't see multiple printk's from the interrupt handler in scenario 1, though. I suppose it depends on what the "do something" step involves ... if it's disabling and re-enabling interrupts maybe that might explain it.

A colleague of mine asked when the flag was being reset to 0. Is that something that "do something" is supposed to be doing? He also said you might need to mark the flag as "volatile" to ensure the compiler causes it re-read the variable each time through the loop.

-- Al

I knew this problem can be solved by a semaphore.. but still curious
to know

Please clarify


Best regards

Mahendravarman Rajarao




-----Original Message-----
From: Stephens, Allan [mailto:allan.stephens(a)windriver.com]
Sent: Wednesday, August 03, 2016 6:58 PM
To: Mahendravarman Rajarao (RBEI/EAA3)
<Mahendravarman.Rajarao(a)in.bosch.com>; devel(a)lists.zephyrproject.org
Subject: [devel] Re: System Design - Need feedback from developers

Mahendravarman Rajarao wrote:

-----Original Message-----
From: Mahendravarman Rajarao (RBEI/EAA3)
[mailto:Mahendravarman.Rajarao(a)in.bosch.com]
Sent: August-03-16 1:20 AM
To: Stephens, Allan; devel(a)lists.zephyrproject.org
Subject: RE: [devel] System Design - Need feedback from developers

Hi Al

Please Clarify the below line

"certain types of object (for example, mailboxes) cannot be used by
interrupt handlers"

1. I have created a Mailbox inside TASK_A. ( taska_mailbox) 2. I
get an interrupt.. In interrupt call back Can I use
task_mailbox_put call to put some data into the taska_mailbox ??
Will Task_A take the data and perform the necessary actions ?
OR I can't use even task_mailbox_put inside interrupt handlers ??
You can't make *any* use of mailboxes from an interrupt handler. To
quote from the "Mailboxes: Concepts" section of the Zephyr Kernel Primer:

"A mailbox allows tasks to exchange messages. A task that sends a
message is known as the sending task, while a task that receives the
message is known as the receiving task. Messages may not be sent or
received by fibers or ISRs, ..."

If you want the interrupt handler to send data to a task, you can use
a nanokernel FIFO to do this. However, your code may need to create a
pool of "message items" that can be queued by the FIFO, in which case
you'll need to ensure the interrupt handler doesn't re-use an item
from the pool unless it has been dequeued and completely processed by the task.

Regards,
Al




Best regards

Mahendravarman Rajarao
RBEI/EAA



-----Original Message-----
From: Stephens, Allan [mailto:allan.stephens(a)windriver.com]
Sent: Wednesday, August 03, 2016 1:10 AM
To: Mahendravarman Rajarao (RBEI/EAA3)
<Mahendravarman.Rajarao(a)in.bosch.com>;
devel(a)lists.zephyrproject.org
Subject: RE: [devel] System Design - Need feedback from developers

See responses below:

-----Original Message-----
From: Mahendravarman rajarao
[mailto:mahendravarman.rajarao(a)in.bosch.com]
Sent: August-01-16 2:49 PM
To: devel(a)lists.zephyrproject.org
Subject: [devel] System Design - Need feedback from developers

Hi

Need clarifications on the system design , Consider the following
example

1. There is a main task named Main_task 2. There are two tasks
TASK_A and TASK_B .. Both these tasks are stared from the Main_task 3.
Main_Task is of higher priority.. Then comes TASK_A priority and
TASK_B priority 4. There is an shared Interrupt with callback
function

Which of the following method best suites for Zephyr environment
with RTOS scheduler ?

1. When Interrupt occurs set a flag in the Intr callback. In the
Main_Task that flags are maintained and

corresponding functions in the TASK_A and TASK_B are called ..

2. Initialize a mailbox in TASK_A and a mailbox for TASK_B . When
Interrupt occurs.. put the message into the TASK_A mailbox and
TASK_B mailbox
based on the message, certains functionality will be execute in
TASK_A and TASK_B

Which design can be used such that RTOS schedules the tasks
properly based on interrupt ?
Is both methods are same w.r.t schdueling or any difference is there ?

Please help
If I understand correctly, you're saying that you've got an
interrupt handler
(ISR) that needs to be able to inform one or more tasks of work that
needs to be done. The standard way of doing this is to have a set of
kernel synchronization objects or kernel data passing objects that
the ISR uses to notify the tasks what they need to do, and have the
tasks wait on these objects. For example, you might have the
following
arrangement:

- TASK_B waits on semaphore B.
- TASK_A waits on semaphore A.
- Main_Task waits on semaphore Main.
- The ISR handles an interrupt, then gives semaphore B, A, or Main
-- or a combination of these -- based on what work it requires the
task(s) to
do.
- The kernel scheduler will then schedule the tasks according to
their
priority.
That is, if Main_Task has work to do it will run first; otherwise,
TASK_A will run if it has work to do; otherwise, TASK _B will run.

Zephyr has a variety of kernel objects that the ISR can use to
notify the
tasks.
If it simply needs to tell a task to "go", you can use a nanokernel
semaphore, a microkernel semaphore, or a microkernel event object.
If it needs to pass additional data to the task, you can use a nanokernel FIFO.

The Zephyr Kernel Primer provides more information about the various
nanokernel and microkernel object types that are available for
synchronization and data passing. However, be sure to note that
certain types of object (for example, mailboxes) cannot be used by
interrupt handlers, which means they won't be suitable for your needs.

Regards,
Al

Join devel@lists.zephyrproject.org to automatically receive all group messages.