[Ovmsdev] Event task
Michael Balzer
dexter at expeedo.de
Sat Apr 7 21:23:57 HKT 2018
Am 07.04.2018 um 12:50 schrieb Mark Webb-Johnson:
> Not sure about freeing the data. It is a void. For a normal malloc pointer I guess it would work, but not for a C++ object. I am happy to provide a SignalEventFree variant to free the void* after the signal is raised.
We could add a virtual "EventData" super class, but then would need to encapsulate all simple structs in that, i.e. all system events.
But I think it would also be OK not being able to pass C++ objects but only plain memory structs. Like with FreeRTOS queues, you tell the system how large your
object is and everything else is up to you.
> I’ve been looking at the way tiT does it (inside lwip). Quite a neat way of packaging up a function call to be executed inside another task. The structure being passed on the queue also contains a semaphore that the sender can wait on, and the semaphore is triggered once the function is done.
>
> How about SignalEventSync and SignalEventAsync variants, with the first one waiting for the signal to be sent before returning?
>
> But the issue is SignalEventSync would not be allowed to be called from within EventTask context (so you can’t call SignalEventSync from within a signal handler). We can protect this within the SignalEventSync function itself by checking the current running task structures.
That sounds complicated. Event handlers raising events would need to be aware of their execution context and need to adapt to it.
I think if we make events asynchronous, they should always be (except when raised from within the EventTask, which can be handled by SignalEvent() itself).
Another idea that can solve both issues: SignalEvent(event, data, [DoneCallback])
DoneCallback(event, data) would be called by the EventTask after listener execution has finished. The callback can implement memory cleanup and/or synchronous
processing (i.e. by a semaphore or task signal) as needed.
Regards,
Michael
>
> Does that satisfy the requirements?
>
> Regards, Mark.
>
>> On 7 Apr 2018, at 5:55 PM, Michael Balzer <dexter at expeedo.de> wrote:
>>
>> A solution for this could be to let SignalEvent() create a copy of the object pointed to, and let the event task free that after calling all listeners.
>>
>> That wouldn't work for nested objects, but would be sufficient for standard event data transport.
>>
>>
>>
>> Am 07.04.2018 um 11:51 schrieb Michael Balzer:
>>> Mark,
>>>
>>> event listeners currently get pointers to objects in the user data field. If we change to asynchronous execution like this, those pointers are no longer valid
>>> if they don't point to static objects.
>>>
>>> I'm using event data pointers for the EMCY detail data transport in my SEVCON module so would need to change that.
>>>
>>> I haven't checked if / where we currently use event data pointers in the framework.
>>>
>>> Regards,
>>> Michael
>>>
>>>
>>> Am 07.04.2018 um 11:26 schrieb Mark Webb-Johnson:
>>>> I’m seeing a timing/stack/mutex/whatever issue with the new 3.1 modules, regarding sd card auto-mounting at boot.
>>>>
>>>> Currently we are using a freertos timer to auto-mount this 500ms after insertion. That fires off some events (sd.inserted, sd.mounted) and I have a script on sd.mounted that does some things like turn on log file to /sd/ovms.log. That is failing (locking up SD). In general, as Michael pointed out, doing big things in freertos timers is not recommended.
>>>>
>>>> I tried a quick fix to change to use ticker.1 and housekeeping timers. But, then in ticker.1 we SignalEvent sd.inserted and sd.mounted, and that leads to a whole new set of problems (raising a signal inside a signal handler).
>>>>
>>>> Overall, it seems messy. The housekeeping task (where we like to run these things) is also very basic at the moment.
>>>>
>>>> I think the better solution maybe to remove the housekeeping task completely, and replace it with an event task reading events off a queue and firing them to all listeners. Then change SignalEvent to queue an event to the event task so that the event task fires the actual event in it’s own time and in it’s own large stack.
>>>>
>>>> The slight change here is that we would still guarantee in-order delivery of events raised, but the caller of SignalEvent would immediately get back control (even if the signal had not been dispatched to all listeners yet).
>>>>
>>>> OK? Any better suggestions?
>>>>
>>>> Regards, Mark
>>>>
>>>> _______________________________________________
>>>> OvmsDev mailing list
>>>> OvmsDev at lists.openvehicles.com
>>>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
>> --
>> Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
>> Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
>>
>> _______________________________________________
>> OvmsDev mailing list
>> OvmsDev at lists.openvehicles.com
>> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
> _______________________________________________
> OvmsDev mailing list
> OvmsDev at lists.openvehicles.com
> http://lists.openvehicles.com/mailman/listinfo/ovmsdev
--
Michael Balzer * Helkenberger Weg 9 * D-58256 Ennepetal
Fon 02333 / 833 5735 * Handy 0176 / 206 989 26
More information about the OvmsDev
mailing list