Re: Timers in a task context

2018-04-11 Thread Joel Sherrill
On Tue, Apr 10, 2018 at 7:20 AM, Matthew J Fletcher 
wrote:

> Hi
>
> It would be good to know if rtems_task_self() is expected to return the
> 'TIME' a.k.a rtems_timer_initiate_server() task id, when a timer created
> with rtems_timer_server_fire_after() fires.
>

Yes. The timer server is just a task which runs at a special high priority.


>
> If it is then i will have to make up some work around, as quite a bit of
> code thats coming over from ThreadX depends on, it returning the previous
> 'user' task, not the previous 'system' task.
>
> Personally it does feel wrong that the behavior of  rtems_task_self()
> changes behavior depending if you use the timer server or not.
>

The ID returned for an ISR based timer function is random. It is the ID of
the thread running when the clock interrupt occurred. It could be the ID of
any thread but assuming your system goes idle, it is more likely to be IDLE
than anything else.

If you want a specific timer instance to send to a specific MQ, then use
the void * argument to pass in information which guides the timer instance.

The timer examples in examples-v2/led pass in the id of the timer instance
to have two timer instances use the same timer service routine.

You could do something similar. Pass in a MQ id or the pointer to a
structure with the required information.

--joel


>
>
>
> On 10 April 2018 at 10:19, Sebastian Huber  brains.de> wrote:
>
>> On 10/04/18 11:11, Matthew J Fletcher wrote:
>>
>>> It looks like a difference in operation to say, for example ThreadX,
>>> who's tx_thread_identify() function is documented similarly "If this
>>> service is called from an ISR the return value represents the thread
>>> running prior to the executing interrupt handler", however in operation in
>>> ThreadX there is no non-service, or raw timer interrupt handler, so it
>>> always returns the previous 'user' threads task.
>>>
>>
>> These timer routines executing in the context of a particular thread look
>> more like a signal. You could use a timer and then send a signal to a task
>> in RTEMS. However, I would not use signals in RTEMS due to their
>> implementation (there is a potential infinite recursion).
>>
>> --
>> Sebastian Huber, embedded brains GmbH
>>
>> Address : Dornierstr. 4, D-82178 Puchheim, Germany
>> Phone   : +49 89 189 47 41-16
>> Fax : +49 89 189 47 41-09
>> E-Mail  : sebastian.hu...@embedded-brains.de
>> PGP : Public key available on request.
>>
>> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>>
>>
>
>
> --
>
> regards
> ---
> Matthew J Fletcher
>
>
> ___
> users mailing list
> users@rtems.org
> http://lists.rtems.org/mailman/listinfo/users
>
___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Re: Timers in a task context

2018-04-11 Thread Sebastian Huber

On 10/04/18 14:20, Matthew J Fletcher wrote:

Hi

It would be good to know if rtems_task_self() is expected to return 
the 'TIME' a.k.a rtems_timer_initiate_server() task id, when a timer 
created with rtems_timer_server_fire_after() fires.


The use of rtems_task_self() in timer routines is a bad application 
behaviour from my point of view. The execution context of the timer 
routines is an implementation detail.




If it is then i will have to make up some work around, as quite a bit 
of code thats coming over from ThreadX depends on, it returning the 
previous 'user' task, not the previous 'system' task.


You can easily fix this with some glue code, e.g.

typedef struct your_timer {
  rtems_id task_which_created_this_timer;
  rtems_id timer;
  void *arg;
  void (*handler)(struct your_timer *, void *);
} your_timer;

void create_timer(your_timer *t)
{
  t->task_which_created_this_timer = rtems_task_self();
  rtems_timer_create(..., >timer);
}

void timer_wrapper(rtems_id timer, void *arg)
{
  your_timer *t = arg;

  (*t->handler)(t, t->arg);
}

void fire_timer(your_timer *t, ...)
{
  rtems_timer_fire_after(..., timer_wrapper, t);
}

rtems_id get_task_which_created_this_timer(const your_timer *t)
{
   return t->task_which_created_this_timer;
}



Personally it does feel wrong that the behavior of rtems_task_self() 
changes behavior depending if you use the timer server or not.


rtems_task_self() returns the id of the executing thread.

--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Re: Timers in a task context

2018-04-10 Thread Sebastian Huber

On 10/04/18 11:11, Matthew J Fletcher wrote:
It looks like a difference in operation to say, for example ThreadX, 
who's tx_thread_identify() function is documented similarly "If this 
service is called from an ISR the return value represents the thread 
running prior to the executing interrupt handler", however in 
operation in ThreadX there is no non-service, or raw timer interrupt 
handler, so it always returns the previous 'user' threads task.


These timer routines executing in the context of a particular thread 
look more like a signal. You could use a timer and then send a signal to 
a task in RTEMS. However, I would not use signals in RTEMS due to their 
implementation (there is a potential infinite recursion).


--
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail  : sebastian.hu...@embedded-brains.de
PGP : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.

___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Re: Timers in a task context

2018-04-10 Thread Matthew J Fletcher
It looks like a difference in operation to say, for example ThreadX, who's
tx_thread_identify() function is documented similarly "If this service is
called from an ISR the return value represents the thread running prior to
the executing interrupt handler", however in operation in ThreadX there is
no non-service, or raw timer interrupt handler, so it always returns the
previous 'user' threads task.

On 10 April 2018 at 09:34, Matthew J Fletcher  wrote:

> Hi,
>
> I think I've managed to narrow it down,. rtems_task_self() is documented
> as "If called from an interrupt service routine, this directive will return
> the Id of the interrupted task.",.. however if you run a timer server and
> your timer is initiated using rtems_timer_server_fire_after(), then
> rtems_task_self() will always return 'TIME'.
>
> It does not give the "user" task executing before the 'TIME' task,..
> as rtems_timer_fire_after() presumably would.
>
>
> On 9 April 2018 at 18:59, Joel Sherrill  wrote:
>
>>
>>
>> On Mon, Apr 9, 2018 at 11:54 AM, Matthew J Fletcher 
>> wrote:
>>
>>> Hi,
>>>
>>> Some other operating systems allow a timer be created that will fire the
>>> associated routine in that tasks context. In rtems timers are either in the
>>> interrupt or the timer task, either way, not in the context of the task
>>> that created the timer.
>>>
>>>
>> FWIW I'm not familiar with an OS that does this.  Happy to see any
>> manuals online.
>>
>>
>>> This has caused me some head scratching,. the existing task does
>>> something like this...
>>>
>>> do_bunch_of_stuff()
>>> {
>>>   forever {
>>>   rtems_message_queue_receive( rtems_task_self () -> rtems_id ,
>>> wait_forever_no_timeout )
>>>   do_something_with_messages_received();
>>>   }
>>> }
>>>
>>
>> I am not 100% sure what you are trying to accomplish but message queues
>> are independent
>> objects that tasks/threads block on. You don't pass in the thread id.
>> Message queues have
>> their own id returned by the rtems_message_queue_create() call.
>>
>>
>>>
>>> while another task does,..
>>>
>>> rtems_timer_create(5_seconds,  do_bunch_of_stuff() );
>>> rtems_message_queue_send( do_bunch_task -> rtems_id, blob1 );
>>> rtems_message_queue_send( do_bunch_task -> rtems_id, blob2 );
>>> rtems_message_queue_send( do_bunch_task -> rtems_id, blob3 );
>>> // etc
>>>
>>> of course when do_bunch_of_stuff() gets invoked by the timer,
>>> rtems_task_self() is not going to magically know the task id to return.
>>>
>>>
>>> Whats the best way to deal with this ?, any method i use (events /
>>> semaphores, etc) is not going to work because there is already an existing
>>> "wait_forever" blocking action,.. i presume i would have to change that to
>>> non-blocking then sample the queue every N ?
>>>
>>>
>>> --
>>>
>>> regards
>>> ---
>>> Matthew J Fletcher
>>>
>>>
>>> ___
>>> users mailing list
>>> users@rtems.org
>>> http://lists.rtems.org/mailman/listinfo/users
>>>
>>
>>
>
>
> --
>
> regards
> ---
> Matthew J Fletcher
>
>


-- 

regards
---
Matthew J Fletcher
___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Re: Timers in a task context

2018-04-10 Thread Matthew J Fletcher
Hi,

I think I've managed to narrow it down,. rtems_task_self() is documented as
"If called from an interrupt service routine, this directive will return
the Id of the interrupted task.",.. however if you run a timer server and
your timer is initiated using rtems_timer_server_fire_after(), then
rtems_task_self() will always return 'TIME'.

It does not give the "user" task executing before the 'TIME' task,..
as rtems_timer_fire_after() presumably would.


On 9 April 2018 at 18:59, Joel Sherrill  wrote:

>
>
> On Mon, Apr 9, 2018 at 11:54 AM, Matthew J Fletcher 
> wrote:
>
>> Hi,
>>
>> Some other operating systems allow a timer be created that will fire the
>> associated routine in that tasks context. In rtems timers are either in the
>> interrupt or the timer task, either way, not in the context of the task
>> that created the timer.
>>
>>
> FWIW I'm not familiar with an OS that does this.  Happy to see any manuals
> online.
>
>
>> This has caused me some head scratching,. the existing task does
>> something like this...
>>
>> do_bunch_of_stuff()
>> {
>>   forever {
>>   rtems_message_queue_receive( rtems_task_self () -> rtems_id ,
>> wait_forever_no_timeout )
>>   do_something_with_messages_received();
>>   }
>> }
>>
>
> I am not 100% sure what you are trying to accomplish but message queues
> are independent
> objects that tasks/threads block on. You don't pass in the thread id.
> Message queues have
> their own id returned by the rtems_message_queue_create() call.
>
>
>>
>> while another task does,..
>>
>> rtems_timer_create(5_seconds,  do_bunch_of_stuff() );
>> rtems_message_queue_send( do_bunch_task -> rtems_id, blob1 );
>> rtems_message_queue_send( do_bunch_task -> rtems_id, blob2 );
>> rtems_message_queue_send( do_bunch_task -> rtems_id, blob3 );
>> // etc
>>
>> of course when do_bunch_of_stuff() gets invoked by the timer,
>> rtems_task_self() is not going to magically know the task id to return.
>>
>>
>> Whats the best way to deal with this ?, any method i use (events /
>> semaphores, etc) is not going to work because there is already an existing
>> "wait_forever" blocking action,.. i presume i would have to change that to
>> non-blocking then sample the queue every N ?
>>
>>
>> --
>>
>> regards
>> ---
>> Matthew J Fletcher
>>
>>
>> ___
>> users mailing list
>> users@rtems.org
>> http://lists.rtems.org/mailman/listinfo/users
>>
>
>


-- 

regards
---
Matthew J Fletcher
___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Re: Timers in a task context

2018-04-09 Thread Joel Sherrill
On Mon, Apr 9, 2018 at 11:54 AM, Matthew J Fletcher 
wrote:

> Hi,
>
> Some other operating systems allow a timer be created that will fire the
> associated routine in that tasks context. In rtems timers are either in the
> interrupt or the timer task, either way, not in the context of the task
> that created the timer.
>
>
FWIW I'm not familiar with an OS that does this.  Happy to see any manuals
online.


> This has caused me some head scratching,. the existing task does something
> like this...
>
> do_bunch_of_stuff()
> {
>   forever {
>   rtems_message_queue_receive( rtems_task_self () -> rtems_id ,
> wait_forever_no_timeout )
>   do_something_with_messages_received();
>   }
> }
>

I am not 100% sure what you are trying to accomplish but message queues are
independent
objects that tasks/threads block on. You don't pass in the thread id.
Message queues have
their own id returned by the rtems_message_queue_create() call.


>
> while another task does,..
>
> rtems_timer_create(5_seconds,  do_bunch_of_stuff() );
> rtems_message_queue_send( do_bunch_task -> rtems_id, blob1 );
> rtems_message_queue_send( do_bunch_task -> rtems_id, blob2 );
> rtems_message_queue_send( do_bunch_task -> rtems_id, blob3 );
> // etc
>
> of course when do_bunch_of_stuff() gets invoked by the timer,
> rtems_task_self() is not going to magically know the task id to return.
>
>
> Whats the best way to deal with this ?, any method i use (events /
> semaphores, etc) is not going to work because there is already an existing
> "wait_forever" blocking action,.. i presume i would have to change that to
> non-blocking then sample the queue every N ?
>
>
> --
>
> regards
> ---
> Matthew J Fletcher
>
>
> ___
> users mailing list
> users@rtems.org
> http://lists.rtems.org/mailman/listinfo/users
>
___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users

Timers in a task context

2018-04-09 Thread Matthew J Fletcher
Hi,

Some other operating systems allow a timer be created that will fire the
associated routine in that tasks context. In rtems timers are either in the
interrupt or the timer task, either way, not in the context of the task
that created the timer.

This has caused me some head scratching,. the existing task does something
like this...

do_bunch_of_stuff()
{
  forever {
  rtems_message_queue_receive( rtems_task_self () -> rtems_id ,
wait_forever_no_timeout )
  do_something_with_messages_received();
  }
}

while another task does,..

rtems_timer_create(5_seconds,  do_bunch_of_stuff() );
rtems_message_queue_send( do_bunch_task -> rtems_id, blob1 );
rtems_message_queue_send( do_bunch_task -> rtems_id, blob2 );
rtems_message_queue_send( do_bunch_task -> rtems_id, blob3 );
// etc

of course when do_bunch_of_stuff() gets invoked by the timer,
rtems_task_self() is not going to magically know the task id to return.


Whats the best way to deal with this ?, any method i use (events /
semaphores, etc) is not going to work because there is already an existing
"wait_forever" blocking action,.. i presume i would have to change that to
non-blocking then sample the queue every N ?


-- 

regards
---
Matthew J Fletcher
___
users mailing list
users@rtems.org
http://lists.rtems.org/mailman/listinfo/users