mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-09 17:38:32 -04:00
AP_Scripting: Support libraries holding the scheduler lock
This commit is contained in:
parent
c257cea375
commit
a0bfc823b3
@ -144,6 +144,7 @@ singleton GCS method set_message_interval MAV_RESULT'enum uint8_t 0 MAVLINK_COMM
|
|||||||
|
|
||||||
include AP_Vehicle/AP_Vehicle.h
|
include AP_Vehicle/AP_Vehicle.h
|
||||||
singleton AP_Vehicle alias vehicle
|
singleton AP_Vehicle alias vehicle
|
||||||
|
singleton AP_Vehicle scheduler-semaphore
|
||||||
singleton AP_Vehicle method set_mode boolean uint8_t 0 UINT8_MAX ModeReason::SCRIPTING'literal
|
singleton AP_Vehicle method set_mode boolean uint8_t 0 UINT8_MAX ModeReason::SCRIPTING'literal
|
||||||
singleton AP_Vehicle method get_mode uint8_t
|
singleton AP_Vehicle method get_mode uint8_t
|
||||||
singleton AP_Vehicle method get_likely_flying boolean
|
singleton AP_Vehicle method get_likely_flying boolean
|
||||||
|
@ -7,20 +7,21 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
char keyword_alias[] = "alias";
|
char keyword_alias[] = "alias";
|
||||||
char keyword_ap_object[] = "ap_object";
|
char keyword_ap_object[] = "ap_object";
|
||||||
char keyword_comment[] = "--";
|
char keyword_comment[] = "--";
|
||||||
char keyword_depends[] = "depends";
|
char keyword_depends[] = "depends";
|
||||||
char keyword_enum[] = "enum";
|
char keyword_enum[] = "enum";
|
||||||
char keyword_field[] = "field";
|
char keyword_field[] = "field";
|
||||||
char keyword_include[] = "include";
|
char keyword_include[] = "include";
|
||||||
char keyword_method[] = "method";
|
char keyword_method[] = "method";
|
||||||
char keyword_operator[] = "operator";
|
char keyword_operator[] = "operator";
|
||||||
char keyword_read[] = "read";
|
char keyword_read[] = "read";
|
||||||
char keyword_semaphore[] = "semaphore";
|
char keyword_scheduler_semaphore[] = "scheduler-semaphore";
|
||||||
char keyword_singleton[] = "singleton";
|
char keyword_semaphore[] = "semaphore";
|
||||||
char keyword_userdata[] = "userdata";
|
char keyword_singleton[] = "singleton";
|
||||||
char keyword_write[] = "write";
|
char keyword_userdata[] = "userdata";
|
||||||
|
char keyword_write[] = "write";
|
||||||
|
|
||||||
// attributes (should include the leading ' )
|
// attributes (should include the leading ' )
|
||||||
char keyword_attr_enum[] = "'enum";
|
char keyword_attr_enum[] = "'enum";
|
||||||
@ -298,7 +299,8 @@ struct userdata_field {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum userdata_flags {
|
enum userdata_flags {
|
||||||
UD_FLAG_SEMAPHORE = (1U << 0),
|
UD_FLAG_SEMAPHORE = (1U << 0),
|
||||||
|
UD_FLAG_SCHEDULER_SEMAPHORE = (1U << 1),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct userdata_enum {
|
struct userdata_enum {
|
||||||
@ -788,6 +790,8 @@ void handle_singleton(void) {
|
|||||||
|
|
||||||
} else if (strcmp(type, keyword_semaphore) == 0) {
|
} else if (strcmp(type, keyword_semaphore) == 0) {
|
||||||
node->flags |= UD_FLAG_SEMAPHORE;
|
node->flags |= UD_FLAG_SEMAPHORE;
|
||||||
|
} else if (strcmp(type, keyword_scheduler_semaphore) == 0) {
|
||||||
|
node->flags |= UD_FLAG_SCHEDULER_SEMAPHORE;
|
||||||
} else if (strcmp(type, keyword_method) == 0) {
|
} else if (strcmp(type, keyword_method) == 0) {
|
||||||
handle_method(node->name, &(node->methods));
|
handle_method(node->name, &(node->methods));
|
||||||
} else if (strcmp(type, keyword_enum) == 0) {
|
} else if (strcmp(type, keyword_enum) == 0) {
|
||||||
@ -845,12 +849,19 @@ void handle_ap_object(void) {
|
|||||||
|
|
||||||
} else if (strcmp(type, keyword_semaphore) == 0) {
|
} else if (strcmp(type, keyword_semaphore) == 0) {
|
||||||
node->flags |= UD_FLAG_SEMAPHORE;
|
node->flags |= UD_FLAG_SEMAPHORE;
|
||||||
|
} else if (strcmp(type, keyword_scheduler_semaphore) == 0) {
|
||||||
|
node->flags |= UD_FLAG_SCHEDULER_SEMAPHORE;
|
||||||
} else if (strcmp(type, keyword_method) == 0) {
|
} else if (strcmp(type, keyword_method) == 0) {
|
||||||
handle_method(node->name, &(node->methods));
|
handle_method(node->name, &(node->methods));
|
||||||
} else {
|
} else {
|
||||||
error(ERROR_SINGLETON, "AP_Objects only support aliases, methods or semaphore keyowrds (got %s)", type);
|
error(ERROR_SINGLETON, "AP_Objects only support aliases, methods or semaphore keyowrds (got %s)", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check that we didn't just add 2 singleton flags
|
||||||
|
if ((node->flags & UD_FLAG_SEMAPHORE) && (node->flags & UD_FLAG_SCHEDULER_SEMAPHORE)) {
|
||||||
|
error(ERROR_SINGLETON, "Taking both a library semaphore and scheduler semaphore is prohibited");
|
||||||
|
}
|
||||||
|
|
||||||
// ensure no more tokens on the line
|
// ensure no more tokens on the line
|
||||||
if (next_token()) {
|
if (next_token()) {
|
||||||
error(ERROR_HEADER, "Singleton contained an unexpected extra token: %s", state.token);
|
error(ERROR_HEADER, "Singleton contained an unexpected extra token: %s", state.token);
|
||||||
@ -1345,6 +1356,10 @@ void emit_userdata_method(const struct userdata *data, const struct method *meth
|
|||||||
fprintf(source, " ud->get_semaphore().take_blocking();\n");
|
fprintf(source, " ud->get_semaphore().take_blocking();\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data->flags & UD_FLAG_SCHEDULER_SEMAPHORE) {
|
||||||
|
fprintf(source, " AP::scheduler().get_semaphore().take_blocking();\n");
|
||||||
|
}
|
||||||
|
|
||||||
switch (method->return_type.type) {
|
switch (method->return_type.type) {
|
||||||
case TYPE_BOOLEAN:
|
case TYPE_BOOLEAN:
|
||||||
fprintf(source, " const bool data = ud->%s(", method->name);
|
fprintf(source, " const bool data = ud->%s(", method->name);
|
||||||
@ -1433,6 +1448,10 @@ void emit_userdata_method(const struct userdata *data, const struct method *meth
|
|||||||
fprintf(source, " ud->get_semaphore().give();\n");
|
fprintf(source, " ud->get_semaphore().give();\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data->flags & UD_FLAG_SCHEDULER_SEMAPHORE) {
|
||||||
|
fprintf(source, " AP::scheduler().get_semaphore().give();\n");
|
||||||
|
}
|
||||||
|
|
||||||
int return_count = 1; // number of arguments to return
|
int return_count = 1; // number of arguments to return
|
||||||
switch (method->return_type.type) {
|
switch (method->return_type.type) {
|
||||||
case TYPE_BOOLEAN:
|
case TYPE_BOOLEAN:
|
||||||
|
@ -735,8 +735,10 @@ static int AP_Vehicle_get_time_flying_ms(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding_argcheck(L, 1);
|
binding_argcheck(L, 1);
|
||||||
|
AP::scheduler().get_semaphore().take_blocking();
|
||||||
const uint32_t data = ud->get_time_flying_ms();
|
const uint32_t data = ud->get_time_flying_ms();
|
||||||
|
|
||||||
|
AP::scheduler().get_semaphore().give();
|
||||||
new_uint32_t(L);
|
new_uint32_t(L);
|
||||||
*static_cast<uint32_t *>(luaL_checkudata(L, -1, "uint32_t")) = data;
|
*static_cast<uint32_t *>(luaL_checkudata(L, -1, "uint32_t")) = data;
|
||||||
return 1;
|
return 1;
|
||||||
@ -749,8 +751,10 @@ static int AP_Vehicle_get_likely_flying(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding_argcheck(L, 1);
|
binding_argcheck(L, 1);
|
||||||
|
AP::scheduler().get_semaphore().take_blocking();
|
||||||
const bool data = ud->get_likely_flying();
|
const bool data = ud->get_likely_flying();
|
||||||
|
|
||||||
|
AP::scheduler().get_semaphore().give();
|
||||||
lua_pushboolean(L, data);
|
lua_pushboolean(L, data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -762,8 +766,10 @@ static int AP_Vehicle_get_mode(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding_argcheck(L, 1);
|
binding_argcheck(L, 1);
|
||||||
|
AP::scheduler().get_semaphore().take_blocking();
|
||||||
const uint8_t data = ud->get_mode();
|
const uint8_t data = ud->get_mode();
|
||||||
|
|
||||||
|
AP::scheduler().get_semaphore().give();
|
||||||
lua_pushinteger(L, data);
|
lua_pushinteger(L, data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -778,10 +784,12 @@ static int AP_Vehicle_set_mode(lua_State *L) {
|
|||||||
const lua_Integer raw_data_2 = luaL_checkinteger(L, 2);
|
const lua_Integer raw_data_2 = luaL_checkinteger(L, 2);
|
||||||
luaL_argcheck(L, ((raw_data_2 >= MAX(0, 0)) && (raw_data_2 <= MIN(UINT8_MAX, UINT8_MAX))), 2, "argument out of range");
|
luaL_argcheck(L, ((raw_data_2 >= MAX(0, 0)) && (raw_data_2 <= MIN(UINT8_MAX, UINT8_MAX))), 2, "argument out of range");
|
||||||
const uint8_t data_2 = static_cast<uint8_t>(raw_data_2);
|
const uint8_t data_2 = static_cast<uint8_t>(raw_data_2);
|
||||||
|
AP::scheduler().get_semaphore().take_blocking();
|
||||||
const bool data = ud->set_mode(
|
const bool data = ud->set_mode(
|
||||||
data_2,
|
data_2,
|
||||||
ModeReason::SCRIPTING);
|
ModeReason::SCRIPTING);
|
||||||
|
|
||||||
|
AP::scheduler().get_semaphore().give();
|
||||||
lua_pushboolean(L, data);
|
lua_pushboolean(L, data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user