fix(fw): lua telemetry handling (#7773)

This commit is contained in:
3djc
2026-09-25 13:47:20 +10:00
committed by GitHub
parent 425944bff2
commit c2cfe393e1
5 changed files with 53 additions and 16 deletions
+16 -10
View File
@@ -1206,13 +1206,19 @@ static int luaCrossfireTelemetryPush(lua_State* L)
if (lua_gettop(L) == 0) {
lua_pushboolean(L, outputTelemetryBuffer.isAvailable());
} else if (lua_gettop(L) > TELEMETRY_OUTPUT_BUFFER_SIZE) {
lua_pushboolean(L, false);
return 1;
} else if (outputTelemetryBuffer.isAvailable()) {
uint8_t command = luaL_checkinteger(L, 1);
luaL_checktype(L, 2, LUA_TTABLE);
uint8_t length = luaL_len(L, 2);
lua_Integer payloadLen = luaL_len(L, 2);
// ADDRESS + LENGTH + COMMAND + payload + CRC (2 bytes for COMMAND_ID)
lua_Integer frameLen = 3 + payloadLen + (command == COMMAND_ID ? 2 : 1);
if (payloadLen < 0 || frameLen > TELEMETRY_OUTPUT_BUFFER_SIZE) {
lua_pushboolean(L, false);
return 1;
}
uint8_t length = (uint8_t)payloadLen;
outputTelemetryBuffer.pushByte(MODULE_ADDRESS);
@@ -1232,6 +1238,7 @@ static int luaCrossfireTelemetryPush(lua_State* L)
for (int i = 0; i < length; i++) {
lua_rawgeti(L, 2, i + 1);
outputTelemetryBuffer.pushByte(luaL_checkinteger(L, -1));
lua_pop(L, 1);
}
// CRC
@@ -1324,20 +1331,18 @@ static int luaGhostTelemetryPush(lua_State * L)
if (lua_gettop(L) == 0) {
lua_pushboolean(L, outputTelemetryBuffer.isAvailable());
}
else if (lua_gettop(L) > TELEMETRY_OUTPUT_BUFFER_SIZE ) {
lua_pushboolean(L, false);
return 1;
}
else if (outputTelemetryBuffer.isAvailable()) {
uint8_t type = luaL_checkinteger(L, 1);
luaL_checktype(L, 2, LUA_TTABLE);
uint8_t length = luaL_len(L, 2); // payload length
lua_Integer payloadLen = luaL_len(L, 2); // payload length
if( length > 10 ) { // max 10B payload
if (payloadLen < 0 || payloadLen > 10) { // max 10B payload
lua_pushboolean(L, false);
return 1;
}
uint8_t length = (uint8_t)payloadLen;
// Ghost frames are fixed 14B:
// address(1B) + len (1B) + type(1B) + payload(10B) + crc(1B)
// -> address + len up-front are inserted later
@@ -1346,6 +1351,7 @@ static int luaGhostTelemetryPush(lua_State * L)
for (; i < length; i++) { // data, max 10B
lua_rawgeti(L, 2, i + 1);
outputTelemetryBuffer.pushByte(luaL_checkinteger(L, -1));
lua_pop(L, 1);
}
for (; i < 10; i++) { // fill zeroes to frame size
outputTelemetryBuffer.pushByte(0);
+1 -2
View File
@@ -617,8 +617,7 @@ LuaScriptManager::~LuaScriptManager()
{
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
if (luaInputTelemetryFifo != nullptr) {
deregisterTelemetryQueue(luaInputTelemetryFifo);
delete luaInputTelemetryFifo;
destroyTelemetryQueue(luaInputTelemetryFifo);
luaInputTelemetryFifo = nullptr;
}
}
+4
View File
@@ -168,6 +168,10 @@ void tasksStart()
{
mutex_create(&audioMutex);
#if defined(LUA)
telemetryQueuesInit();
#endif
#if defined(CLI) && !defined(SIMU)
cliStart();
#endif
+22 -3
View File
@@ -22,6 +22,7 @@
#include "edgetx.h"
#include "multi.h"
#include "os/async.h"
#include "os/task.h"
#include "os/timer.h"
#include "pulses/afhds3.h"
#include "pulses/flysky.h"
@@ -459,15 +460,30 @@ TelemetryQueue* luaInputTelemetryFifo = nullptr;
#if defined(COLORLCD)
std::list<TelemetryQueue*> telemetryQueues;
// Scripts register / destroy their queue from the menus task, while frames are
// pushed into them from the timer task (telemetry RX runs there, at a higher
// priority). Both the list and the queue lifetime need to be serialised.
static mutex_handle_t telemetryQueueMutex;
void telemetryQueuesInit()
{
mutex_create(&telemetryQueueMutex);
}
void registerTelemetryQueue(TelemetryQueue* queue)
{
MutexLock lock = MutexLock::MakeInstance(&telemetryQueueMutex);
telemetryQueues.emplace_back(queue);
}
void deregisterTelemetryQueue(TelemetryQueue* queue)
void destroyTelemetryQueue(TelemetryQueue* queue)
{
MutexLock lock = MutexLock::MakeInstance(&telemetryQueueMutex);
telemetryQueues.remove(queue);
delete queue;
}
#else
void telemetryQueuesInit() {}
#endif
static void pushDataToQueue(TelemetryQueue* queue, uint8_t* data, int length)
@@ -482,8 +498,11 @@ static void pushDataToQueue(TelemetryQueue* queue, uint8_t* data, int length)
void pushTelemetryDataToQueues(uint8_t* data, int length)
{
#if defined(COLORLCD)
for (auto it = telemetryQueues.cbegin(); it != telemetryQueues.cend(); ++it)
pushDataToQueue(*it, data, length);
{
MutexLock lock = MutexLock::MakeInstance(&telemetryQueueMutex);
for (auto it = telemetryQueues.cbegin(); it != telemetryQueues.cend(); ++it)
pushDataToQueue(*it, data, length);
}
#endif
pushDataToQueue(luaInputTelemetryFifo, data, length);
}
+10 -1
View File
@@ -237,8 +237,17 @@ extern OutputTelemetryBuffer outputTelemetryBuffer __DMA_NO_CACHE;
#define LUA_TELEMETRY_INPUT_FIFO_SIZE 256
typedef Fifo<uint8_t, LUA_TELEMETRY_INPUT_FIFO_SIZE> TelemetryQueue;
extern TelemetryQueue* luaInputTelemetryFifo;
// Create the lock protecting the queue list. Must be called before the
// scheduler is started.
void telemetryQueuesInit();
void registerTelemetryQueue(TelemetryQueue*);
void deregisterTelemetryQueue(TelemetryQueue*);
// Unregister and delete in one go: the producer runs in the timer task and
// would otherwise be able to write into a queue that has just been freed.
void destroyTelemetryQueue(TelemetryQueue*);
void pushTelemetryDataToQueues(uint8_t* data, int length);
#endif