You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I did some experimentation over the weekend to understand how to propagate events from an interrupt on Pico to JavaScript. This is a fundamental low-level operation in the Moddable SDK used a several places. For example in the Digital Monitor class uses it to call a JavaScript function when a digital input changes.
The usual mechanism in the Moddable SDK for this is the modMessagePostToMachineFromISR function in the host, which is called inside an interrupt handler to queue a native callback for delivery when JavaScript execution is safe. The main challenge is waking up the main loop when a message is ready. The CPU is sleep mode when there's nothing to do. In ARM terms, it is waiting for an event (WFE) and the way to break out of that is to execute the Set Event (SEV) instruction.
The call to sleep (actually sleep_ms) is in modMessageService. The Pico sleep APIs sleep for the time requested. If any events occur before the timeout, Pico goes back to sleep. The solution is to implement sleep using the low level best_effort_wfe_or_timeout which sleeps for the time requested or until an event occurs. That gives a loop something like this to sleep for maxDelayMS milliseconds or until a message is ready.
absolute_time_t until = make_timeout_time_ms(maxDelayMS);
while ([[no message available]]) {
best_effort_wfe_or_timeout(until);
if (to_us_since_boot(get_absolute_time()) >= to_us_since_boot(until))
break;
}
With that in place, I was able to get the hardware alarms to work with XS. For example, these fragments trace "alarm" to the JavaScript console after one second.
// set the alarmadd_alarm_in_ms(1000, alarmOn, the, true);
// interrupt handler -- called when alarm expiresstaticint64_talarmOn(alarm_id_tid, void*user_data)
{
modMessagePostToMachineFromISR((xsMachine*the)user_data, deliverAlarm, NULL);
}
// XS in C function to deliver message to JavaScriptstaticvoiddeliverAlarm(void*the, void*refcon, uint8_t*message, uint16_tmessageLength)
{
xsBeginHost(the);
xsTrace("alarm\n");
xsEndHost(the);
}
The trace occurs at a time when it is safe to invoke JavaScript callbacks, so this technique could be used to implement Digital Monitor's callback on GPIO input change using the (slightly strange) gpio_set_irq_enabled_with_callback API. I got that working late Sunday.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I did some experimentation over the weekend to understand how to propagate events from an interrupt on Pico to JavaScript. This is a fundamental low-level operation in the Moddable SDK used a several places. For example in the Digital Monitor class uses it to call a JavaScript function when a digital input changes.
The usual mechanism in the Moddable SDK for this is the
modMessagePostToMachineFromISR
function in the host, which is called inside an interrupt handler to queue a native callback for delivery when JavaScript execution is safe. The main challenge is waking up the main loop when a message is ready. The CPU is sleep mode when there's nothing to do. In ARM terms, it is waiting for an event (WFE) and the way to break out of that is to execute the Set Event (SEV) instruction.The call to sleep (actually
sleep_ms
) is inmodMessageService
. The Pico sleep APIs sleep for the time requested. If any events occur before the timeout, Pico goes back to sleep. The solution is to implement sleep using the low levelbest_effort_wfe_or_timeout
which sleeps for the time requested or until an event occurs. That gives a loop something like this to sleep formaxDelayMS
milliseconds or until a message is ready.With that in place, I was able to get the hardware alarms to work with XS. For example, these fragments trace "alarm" to the JavaScript console after one second.
The trace occurs at a time when it is safe to invoke JavaScript callbacks, so this technique could be used to implement Digital Monitor's callback on GPIO input change using the (slightly strange)
gpio_set_irq_enabled_with_callback
API. I got that working late Sunday.Beta Was this translation helpful? Give feedback.
All reactions