mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 02:16:53 +08:00
Create system state entry in dataman - ATTN Anton
Create persistent system state id for data manager to store system state that will persist across resets.
This commit is contained in:
@@ -402,6 +402,11 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Start the datamanager
|
||||||
|
#
|
||||||
|
dataman start
|
||||||
|
|
||||||
#
|
#
|
||||||
# MAVLink
|
# MAVLink
|
||||||
#
|
#
|
||||||
@@ -544,11 +549,6 @@ then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
|
||||||
# Start the datamanager
|
|
||||||
#
|
|
||||||
dataman start
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Start the navigator
|
# Start the navigator
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ __EXPORT int dataman_main(int argc, char *argv[]);
|
|||||||
__EXPORT ssize_t dm_read(dm_item_t item, unsigned char index, void *buffer, size_t buflen);
|
__EXPORT ssize_t dm_read(dm_item_t item, unsigned char index, void *buffer, size_t buflen);
|
||||||
__EXPORT ssize_t dm_write(dm_item_t item, unsigned char index, dm_persitence_t persistence, const void *buffer, size_t buflen);
|
__EXPORT ssize_t dm_write(dm_item_t item, unsigned char index, dm_persitence_t persistence, const void *buffer, size_t buflen);
|
||||||
__EXPORT int dm_clear(dm_item_t item);
|
__EXPORT int dm_clear(dm_item_t item);
|
||||||
|
__EXPORT void dm_lock(dm_item_t item);
|
||||||
|
__EXPORT void dm_unlock(dm_item_t item);
|
||||||
__EXPORT int dm_restart(dm_reset_reason restart_type);
|
__EXPORT int dm_restart(dm_reset_reason restart_type);
|
||||||
|
|
||||||
/** Types of function calls supported by the worker task */
|
/** Types of function calls supported by the worker task */
|
||||||
@@ -113,12 +115,17 @@ static const unsigned g_per_item_max_index[DM_KEY_NUM_KEYS] = {
|
|||||||
DM_KEY_FENCE_POINTS_MAX,
|
DM_KEY_FENCE_POINTS_MAX,
|
||||||
DM_KEY_WAYPOINTS_OFFBOARD_0_MAX,
|
DM_KEY_WAYPOINTS_OFFBOARD_0_MAX,
|
||||||
DM_KEY_WAYPOINTS_OFFBOARD_1_MAX,
|
DM_KEY_WAYPOINTS_OFFBOARD_1_MAX,
|
||||||
DM_KEY_WAYPOINTS_ONBOARD_MAX
|
DM_KEY_WAYPOINTS_ONBOARD_MAX,
|
||||||
|
DM_KEY_SYSTEM_STATE_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Table of offset for index 0 of each item type */
|
/* Table of offset for index 0 of each item type */
|
||||||
static unsigned int g_key_offsets[DM_KEY_NUM_KEYS];
|
static unsigned int g_key_offsets[DM_KEY_NUM_KEYS];
|
||||||
|
|
||||||
|
/* Item type lock mutexes */
|
||||||
|
static sem_t *g_item_locks[DM_KEY_NUM_KEYS];
|
||||||
|
static sem_t g_sys_state_mutex;
|
||||||
|
|
||||||
/* The data manager store file handle and file name */
|
/* The data manager store file handle and file name */
|
||||||
static int g_fd = -1, g_task_fd = -1;
|
static int g_fd = -1, g_task_fd = -1;
|
||||||
static const char *k_data_manager_device_path = "/fs/microsd/dataman";
|
static const char *k_data_manager_device_path = "/fs/microsd/dataman";
|
||||||
@@ -567,6 +574,32 @@ dm_clear(dm_item_t item)
|
|||||||
return enqueue_work_item_and_wait_for_result(work);
|
return enqueue_work_item_and_wait_for_result(work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__EXPORT void
|
||||||
|
dm_lock(dm_item_t item)
|
||||||
|
{
|
||||||
|
/* Make sure data manager has been started and is not shutting down */
|
||||||
|
if ((g_fd < 0) || g_task_should_exit)
|
||||||
|
return;
|
||||||
|
if (item >= DM_KEY_NUM_KEYS)
|
||||||
|
return;
|
||||||
|
if (g_item_locks[item]) {
|
||||||
|
sem_wait(g_item_locks[item]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__EXPORT void
|
||||||
|
dm_unlock(dm_item_t item)
|
||||||
|
{
|
||||||
|
/* Make sure data manager has been started and is not shutting down */
|
||||||
|
if ((g_fd < 0) || g_task_should_exit)
|
||||||
|
return;
|
||||||
|
if (item >= DM_KEY_NUM_KEYS)
|
||||||
|
return;
|
||||||
|
if (g_item_locks[item]) {
|
||||||
|
sem_post(g_item_locks[item]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Tell the data manager about the type of the last reset */
|
/* Tell the data manager about the type of the last reset */
|
||||||
__EXPORT int
|
__EXPORT int
|
||||||
dm_restart(dm_reset_reason reason)
|
dm_restart(dm_reset_reason reason)
|
||||||
@@ -607,6 +640,12 @@ task_main(int argc, char *argv[])
|
|||||||
for (unsigned i = 0; i < dm_number_of_funcs; i++)
|
for (unsigned i = 0; i < dm_number_of_funcs; i++)
|
||||||
g_func_counts[i] = 0;
|
g_func_counts[i] = 0;
|
||||||
|
|
||||||
|
/* Initialize the item type locks, for now only DM_KEY_SYSTEM_STATE supports locking */
|
||||||
|
sem_init(&g_sys_state_mutex, 1, 1); /* Initially unlocked */
|
||||||
|
for (unsigned i = 0; i < DM_KEY_NUM_KEYS; i++)
|
||||||
|
g_item_locks[i] = NULL;
|
||||||
|
g_item_locks[DM_KEY_SYSTEM_STATE] = &g_sys_state_mutex;
|
||||||
|
|
||||||
g_task_should_exit = false;
|
g_task_should_exit = false;
|
||||||
|
|
||||||
init_q(&g_work_q);
|
init_q(&g_work_q);
|
||||||
@@ -742,6 +781,7 @@ task_main(int argc, char *argv[])
|
|||||||
destroy_q(&g_work_q);
|
destroy_q(&g_work_q);
|
||||||
destroy_q(&g_free_q);
|
destroy_q(&g_free_q);
|
||||||
sem_destroy(&g_work_queued_sema);
|
sem_destroy(&g_work_queued_sema);
|
||||||
|
sem_destroy(&g_sys_state_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ extern "C" {
|
|||||||
DM_KEY_WAYPOINTS_OFFBOARD_0, /* Mission way point coordinates sent over mavlink */
|
DM_KEY_WAYPOINTS_OFFBOARD_0, /* Mission way point coordinates sent over mavlink */
|
||||||
DM_KEY_WAYPOINTS_OFFBOARD_1, /* (alernate between 0 and 1) */
|
DM_KEY_WAYPOINTS_OFFBOARD_1, /* (alernate between 0 and 1) */
|
||||||
DM_KEY_WAYPOINTS_ONBOARD, /* Mission way point coordinates generated onboard */
|
DM_KEY_WAYPOINTS_ONBOARD, /* Mission way point coordinates generated onboard */
|
||||||
|
DM_KEY_SYSTEM_STATE, /* Persistent system state storage */
|
||||||
DM_KEY_NUM_KEYS /* Total number of item types defined */
|
DM_KEY_NUM_KEYS /* Total number of item types defined */
|
||||||
} dm_item_t;
|
} dm_item_t;
|
||||||
|
|
||||||
@@ -62,7 +63,8 @@ extern "C" {
|
|||||||
DM_KEY_FENCE_POINTS_MAX = GEOFENCE_MAX_VERTICES,
|
DM_KEY_FENCE_POINTS_MAX = GEOFENCE_MAX_VERTICES,
|
||||||
DM_KEY_WAYPOINTS_OFFBOARD_0_MAX = NUM_MISSIONS_SUPPORTED,
|
DM_KEY_WAYPOINTS_OFFBOARD_0_MAX = NUM_MISSIONS_SUPPORTED,
|
||||||
DM_KEY_WAYPOINTS_OFFBOARD_1_MAX = NUM_MISSIONS_SUPPORTED,
|
DM_KEY_WAYPOINTS_OFFBOARD_1_MAX = NUM_MISSIONS_SUPPORTED,
|
||||||
DM_KEY_WAYPOINTS_ONBOARD_MAX = NUM_MISSIONS_SUPPORTED
|
DM_KEY_WAYPOINTS_ONBOARD_MAX = NUM_MISSIONS_SUPPORTED,
|
||||||
|
DM_KEY_SYSTEM_STATE_MAX = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Data persistence levels */
|
/** Data persistence levels */
|
||||||
@@ -101,6 +103,18 @@ extern "C" {
|
|||||||
size_t buflen /* Length in bytes of data to retrieve */
|
size_t buflen /* Length in bytes of data to retrieve */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/** Lock all items of this type */
|
||||||
|
__EXPORT void
|
||||||
|
dm_lock(
|
||||||
|
dm_item_t item /* The item type to clear */
|
||||||
|
);
|
||||||
|
|
||||||
|
/** Unlock all items of this type */
|
||||||
|
__EXPORT void
|
||||||
|
dm_unlock(
|
||||||
|
dm_item_t item /* The item type to clear */
|
||||||
|
);
|
||||||
|
|
||||||
/** Erase all items of this type */
|
/** Erase all items of this type */
|
||||||
__EXPORT int
|
__EXPORT int
|
||||||
dm_clear(
|
dm_clear(
|
||||||
@@ -113,6 +127,16 @@ extern "C" {
|
|||||||
dm_reset_reason restart_type /* The last reset type */
|
dm_reset_reason restart_type /* The last reset type */
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/* NOTE: The following structure defines the persistent system state data stored in the single
|
||||||
|
entry DM_KEY_SYSTEM_STATE_KEY item type. It contains global system state information that
|
||||||
|
needs to survive restarts. This definition is application specific so it doesn't really belong
|
||||||
|
in this header, but till I find it a better home here it is */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char current_offboard_waypoint_id; /* the index of the active offboard waypoint data */
|
||||||
|
/* (DM_KEY_WAYPOINTS_OFFBOARD_n) or -1 for none */
|
||||||
|
} persistent_system_state_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -952,6 +952,8 @@ int Mavlink::map_mission_item_to_mavlink_mission_item(const struct mission_item_
|
|||||||
|
|
||||||
void Mavlink::mavlink_wpm_init(mavlink_wpm_storage *state)
|
void Mavlink::mavlink_wpm_init(mavlink_wpm_storage *state)
|
||||||
{
|
{
|
||||||
|
persistent_system_state_t sys_state;
|
||||||
|
|
||||||
state->size = 0;
|
state->size = 0;
|
||||||
state->max_size = MAVLINK_WPM_MAX_WP_COUNT;
|
state->max_size = MAVLINK_WPM_MAX_WP_COUNT;
|
||||||
state->current_state = MAVLINK_WPM_STATE_IDLE;
|
state->current_state = MAVLINK_WPM_STATE_IDLE;
|
||||||
@@ -962,6 +964,10 @@ void Mavlink::mavlink_wpm_init(mavlink_wpm_storage *state)
|
|||||||
state->timestamp_last_send_request = 0;
|
state->timestamp_last_send_request = 0;
|
||||||
state->timeout = MAVLINK_WPM_PROTOCOL_TIMEOUT_DEFAULT;
|
state->timeout = MAVLINK_WPM_PROTOCOL_TIMEOUT_DEFAULT;
|
||||||
state->current_dataman_id = 0;
|
state->current_dataman_id = 0;
|
||||||
|
if (dm_read(DM_KEY_SYSTEM_STATE, 0, &sys_state, sizeof(sys_state)) == sizeof(sys_state)) {
|
||||||
|
if ((sys_state.current_offboard_waypoint_id >= 0) && (sys_state.current_offboard_waypoint_id <= 1))
|
||||||
|
state->current_dataman_id = sys_state.current_offboard_waypoint_id;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -1428,12 +1434,38 @@ void Mavlink::mavlink_wpm_message_handler(const mavlink_message_t *msg)
|
|||||||
mission.dataman_id = 0;
|
mission.dataman_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dm_write(dm_next, wp.seq, DM_PERSIST_IN_FLIGHT_RESET, &mission_item, len) != len) {
|
if (dm_write(dm_next, wp.seq, DM_PERSIST_POWER_ON_RESET, &mission_item, len) != len) {
|
||||||
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ERROR);
|
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ERROR);
|
||||||
mavlink_missionlib_send_gcs_string("#audio: Unable to write on micro SD");
|
mavlink_missionlib_send_gcs_string("#audio: Unable to write on micro SD");
|
||||||
_wpm->current_state = MAVLINK_WPM_STATE_IDLE;
|
_wpm->current_state = MAVLINK_WPM_STATE_IDLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// offboard mission data saved correctly, now update the persistent system state
|
||||||
|
{
|
||||||
|
persistent_system_state_t state;
|
||||||
|
bool dm_result;
|
||||||
|
// Since we are doing a read-modify-write we must lock the item type
|
||||||
|
dm_lock(DM_KEY_SYSTEM_STATE);
|
||||||
|
// first read in the current state data. There may eventually be data other than the offboard index
|
||||||
|
// and we must preserve it
|
||||||
|
if (dm_read(DM_KEY_SYSTEM_STATE, 0, &state, sizeof(state)) != sizeof(state)) {
|
||||||
|
// Not sure how to handle this? It means that either the item was never
|
||||||
|
// written, or fields have been added to the system state struct. In any case
|
||||||
|
// fields that may not be ours need to be initialized to sane values.
|
||||||
|
// For now the offboard index is the only field, so for now there
|
||||||
|
// is nothing to do here.
|
||||||
|
}
|
||||||
|
state.current_offboard_waypoint_id = mission.dataman_id;
|
||||||
|
dm_result = dm_write(DM_KEY_SYSTEM_STATE, 0, DM_PERSIST_POWER_ON_RESET, &state, sizeof(state)) != sizeof(state);
|
||||||
|
dm_unlock(DM_KEY_SYSTEM_STATE);
|
||||||
|
if (dm_result) {
|
||||||
|
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ERROR);
|
||||||
|
mavlink_missionlib_send_gcs_string("#audio: Unable to write on micro SD");
|
||||||
|
_wpm->current_state = MAVLINK_WPM_STATE_IDLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if (wp.current) {
|
// if (wp.current) {
|
||||||
// warnx("current is: %d", wp.seq);
|
// warnx("current is: %d", wp.seq);
|
||||||
@@ -1485,7 +1517,25 @@ void Mavlink::mavlink_wpm_message_handler(const mavlink_message_t *msg)
|
|||||||
publish_mission();
|
publish_mission();
|
||||||
|
|
||||||
if (dm_clear(DM_KEY_WAYPOINTS_OFFBOARD_0) == OK && dm_clear(DM_KEY_WAYPOINTS_OFFBOARD_1) == OK) {
|
if (dm_clear(DM_KEY_WAYPOINTS_OFFBOARD_0) == OK && dm_clear(DM_KEY_WAYPOINTS_OFFBOARD_1) == OK) {
|
||||||
|
persistent_system_state_t state;
|
||||||
|
bool dm_result;
|
||||||
|
dm_lock(DM_KEY_SYSTEM_STATE);
|
||||||
|
// first read in the current state data. There may eventually be data other than the offboard index
|
||||||
|
// and we must preserve it
|
||||||
|
if (dm_read(DM_KEY_SYSTEM_STATE, 0, &state, sizeof(state)) != sizeof(state)) {
|
||||||
|
// Not sure how to handle this? It means that either the item was never
|
||||||
|
// written, or fields have been added to the system state struct. In any case
|
||||||
|
// fields that may not be ours need to be initialized to sane values.
|
||||||
|
// For now the offboard index is the only field, so we can deal with it here.
|
||||||
|
}
|
||||||
|
state.current_offboard_waypoint_id = -1;
|
||||||
|
dm_result = dm_write(DM_KEY_SYSTEM_STATE, 0, DM_PERSIST_POWER_ON_RESET, &state, sizeof(state)) == sizeof(state);
|
||||||
|
dm_unlock(DM_KEY_SYSTEM_STATE);
|
||||||
|
if (dm_result) {
|
||||||
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ACCEPTED);
|
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ACCEPTED);
|
||||||
|
} else {
|
||||||
|
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ERROR);
|
mavlink_wpm_send_waypoint_ack(_wpm->current_partner_sysid, _wpm->current_partner_compid, MAV_MISSION_ERROR);
|
||||||
|
|||||||
@@ -603,6 +603,15 @@ Navigator::task_main()
|
|||||||
warnx("Could not clear geofence");
|
warnx("Could not clear geofence");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // *** UNTESTED... Anton, this is for you
|
||||||
|
/* Get the last offboard mission id */
|
||||||
|
persistent_system_state_t sys_state;
|
||||||
|
if (dm_read(DM_KEY_SYSTEM_STATE, 0, &sys_state, sizeof(sys_state)) == sizeof(sys_state)) {
|
||||||
|
if ((sys_state.current_offboard_waypoint_id >= 0) && (sys_state.current_offboard_waypoint_id <= 1))
|
||||||
|
_mission.set_offboard_dataman_id(sys_state.current_offboard_waypoint_id);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do subscriptions
|
* do subscriptions
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user