mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-17 06:40:35 +08:00
fix power button shutdown: use an orb topic instead of a work queue call
px4_shutdown_request() was called from the power button IRQ callback, which invoked a work queue callback. But on NuttX, the work queue uses a semaphore, and thus it cannot be called from IRQ context. This patch switches to publishing an uORB msg instead, which is handled in the commander main thread. To increase failure resistance, we could subscribe to the same topic in another module for redundancy, in case commander runs wild.
This commit is contained in:
@@ -104,6 +104,7 @@
|
||||
#include <uORB/topics/mission_result.h>
|
||||
#include <uORB/topics/offboard_control_mode.h>
|
||||
#include <uORB/topics/position_setpoint_triplet.h>
|
||||
#include <uORB/topics/power_button_state.h>
|
||||
#include <uORB/topics/vehicle_roi.h>
|
||||
#include <uORB/topics/parameter_update.h>
|
||||
#include <uORB/topics/safety.h>
|
||||
@@ -174,6 +175,8 @@ static int64_t lvel_probation_time_us = POSVEL_PROBATION_TAKEOFF;
|
||||
/* Mavlink log uORB handle */
|
||||
static orb_advert_t mavlink_log_pub = nullptr;
|
||||
|
||||
static orb_advert_t power_button_state_pub = nullptr;
|
||||
|
||||
/* System autostart ID */
|
||||
static int autostart_id;
|
||||
|
||||
@@ -334,11 +337,34 @@ static void publish_status_flags(orb_advert_t &vehicle_status_flags_pub);
|
||||
|
||||
static int power_button_state_notification_cb(board_power_button_state_notification_e request)
|
||||
{
|
||||
// Note: this can be called from IRQ handlers
|
||||
if (request == PWR_BUTTON_REQUEST_SHUT_DOWN) {
|
||||
px4_shutdown_request(false, false);
|
||||
// Note: this can be called from IRQ handlers, so we publish a message that will be handled
|
||||
// on the main thread of commander.
|
||||
power_button_state_s button_state;
|
||||
button_state.timestamp = hrt_absolute_time();
|
||||
int ret = PWR_BUTTON_RESPONSE_SHUT_DOWN_PENDING;
|
||||
|
||||
switch(request) {
|
||||
case PWR_BUTTON_IDEL:
|
||||
button_state.event = power_button_state_s::PWR_BUTTON_STATE_IDEL;
|
||||
break;
|
||||
case PWR_BUTTON_DOWN:
|
||||
button_state.event = power_button_state_s::PWR_BUTTON_STATE_DOWN;
|
||||
break;
|
||||
case PWR_BUTTON_UP:
|
||||
button_state.event = power_button_state_s::PWR_BUTTON_STATE_UP;
|
||||
break;
|
||||
case PWR_BUTTON_REQUEST_SHUT_DOWN:
|
||||
button_state.event = power_button_state_s::PWR_BUTTON_STATE_REQUEST_SHUTDOWN;
|
||||
break;
|
||||
default:
|
||||
PX4_ERR("unhandled power button state: %i", (int)request);
|
||||
return ret;
|
||||
}
|
||||
return PWR_BUTTON_RESPONSE_SHUT_DOWN_PENDING;
|
||||
|
||||
int instance;
|
||||
orb_publish_auto(ORB_ID(power_button_state), &power_button_state_pub, &button_state, &instance, ORB_PRIO_DEFAULT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int commander_main(int argc, char *argv[])
|
||||
@@ -1641,6 +1667,8 @@ int commander_thread_main(int argc, char *argv[])
|
||||
struct system_power_s system_power;
|
||||
memset(&system_power, 0, sizeof(system_power));
|
||||
|
||||
int power_button_state_sub = orb_subscribe(ORB_ID(power_button_state));
|
||||
|
||||
/* Subscribe to actuator controls (outputs) */
|
||||
int actuator_controls_sub = orb_subscribe(ORB_ID_VEHICLE_ATTITUDE_CONTROLS);
|
||||
struct actuator_controls_s actuator_controls;
|
||||
@@ -1878,6 +1906,17 @@ int commander_thread_main(int argc, char *argv[])
|
||||
param_init_forced = false;
|
||||
}
|
||||
|
||||
/* handle power button state */
|
||||
orb_check(power_button_state_sub, &updated);
|
||||
|
||||
if (updated) {
|
||||
power_button_state_s button_state;
|
||||
orb_copy(ORB_ID(power_button_state), power_button_state_sub, &button_state);
|
||||
if (button_state.event == power_button_state_s::PWR_BUTTON_STATE_REQUEST_SHUTDOWN) {
|
||||
px4_shutdown_request(false, false);
|
||||
}
|
||||
}
|
||||
|
||||
orb_check(sp_man_sub, &updated);
|
||||
|
||||
if (updated) {
|
||||
|
||||
Reference in New Issue
Block a user