lua hooks for CAN tx (#2967)
* CanTxMessage usable from unit test * testLuaReturnsNil * CAN hook and tests * it helps if parameter names exist * nameless params * s * redefinition of default argument Co-authored-by: Matthew Kennedy <makenne@microsoft.com>
This commit is contained in:
parent
d70754d3a8
commit
45d185b09d
|
@ -370,6 +370,18 @@ int testLuaReturnsInteger(const char* script) {
|
||||||
return lua_tointeger(ls, -1);
|
return lua_tointeger(ls, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testLuaExecString(const char* script) {
|
||||||
|
auto ls = setupLuaState();
|
||||||
|
|
||||||
|
if (!ls) {
|
||||||
|
throw new std::logic_error("Call to setupLuaState failed, returned null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loadScript(ls, script)) {
|
||||||
|
throw new std::logic_error("Call to loadScript failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif // EFI_UNIT_TEST
|
#endif // EFI_UNIT_TEST
|
||||||
|
|
||||||
#endif // EFI_LUA
|
#endif // EFI_LUA
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "airmass.h"
|
#include "airmass.h"
|
||||||
#include "lua_airmass.h"
|
#include "lua_airmass.h"
|
||||||
#include "pwm_generator_logic.h"
|
#include "pwm_generator_logic.h"
|
||||||
|
#include "can_msg_tx.h"
|
||||||
|
|
||||||
// Some functions lean on existing FSIO implementation
|
// Some functions lean on existing FSIO implementation
|
||||||
#include "fsio_impl.h"
|
#include "fsio_impl.h"
|
||||||
|
@ -67,6 +68,62 @@ static int lua_table3d(lua_State* l) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lua_txCan(lua_State* l) {
|
||||||
|
auto channel = luaL_checkinteger(l, 1);
|
||||||
|
// TODO: support multiple channels
|
||||||
|
luaL_argcheck(l, channel == 1, 1, "only channel 1 currently supported");
|
||||||
|
|
||||||
|
auto id = luaL_checkinteger(l, 2);
|
||||||
|
auto ext = luaL_checkinteger(l, 3);
|
||||||
|
|
||||||
|
// Check that ID is valid based on std vs. ext
|
||||||
|
if (ext == 0) {
|
||||||
|
luaL_argcheck(l, id <= 0x7FF, 2, "ID specified is greater than max std ID");
|
||||||
|
} else {
|
||||||
|
luaL_argcheck(l, id <= 0x1FFF'FFFF, 2, "ID specified is greater than max ext ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_checktype(l, 4, LUA_TTABLE);
|
||||||
|
|
||||||
|
// conform ext parameter to true/false
|
||||||
|
CanTxMessage msg(id, 8, ext == 0 ? false : true);
|
||||||
|
|
||||||
|
// Unfortunately there is no way to inspect the length of a table,
|
||||||
|
// so we have to just iterate until we run out of numbers
|
||||||
|
uint8_t dlc = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
lua_pushnumber(l, dlc + 1);
|
||||||
|
auto elementType = lua_gettable(l, 4);
|
||||||
|
auto val = lua_tointeger(l, -1);
|
||||||
|
lua_pop(l, 1);
|
||||||
|
|
||||||
|
if (elementType == LUA_TNIL) {
|
||||||
|
// we're done, this is the end of the array.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (elementType != LUA_TNUMBER) {
|
||||||
|
// We're not at the end, but this isn't a number!
|
||||||
|
luaL_error(l, "Unexpected CAN data at position %d: %s", dlc, lua_tostring(l, -1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This element is valid, increment DLC
|
||||||
|
dlc++;
|
||||||
|
|
||||||
|
if (dlc > 8) {
|
||||||
|
luaL_error(l, "CAN frame length cannot be longer than 8");
|
||||||
|
}
|
||||||
|
|
||||||
|
msg[dlc - 1] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.setDlc(dlc);
|
||||||
|
|
||||||
|
// no return value
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static LuaAirmass luaAirmass;
|
static LuaAirmass luaAirmass;
|
||||||
|
|
||||||
AirmassModelBase& getLuaAirmassModel() {
|
AirmassModelBase& getLuaAirmassModel() {
|
||||||
|
@ -235,6 +292,7 @@ void configureRusefiLuaHooks(lua_State* l) {
|
||||||
lua_register(l, "getSensorRaw", lua_getSensorRaw);
|
lua_register(l, "getSensorRaw", lua_getSensorRaw);
|
||||||
lua_register(l, "hasSensor", lua_hasSensor);
|
lua_register(l, "hasSensor", lua_hasSensor);
|
||||||
lua_register(l, "table3d", lua_table3d);
|
lua_register(l, "table3d", lua_table3d);
|
||||||
|
lua_register(l, "txCan", lua_txCan);
|
||||||
|
|
||||||
#if !EFI_UNIT_TEST
|
#if !EFI_UNIT_TEST
|
||||||
lua_register(l, "startPwm", lua_startPwm);
|
lua_register(l, "startPwm", lua_startPwm);
|
||||||
|
|
|
@ -10,4 +10,5 @@ void startLua();
|
||||||
expected<float> testLuaReturnsNumberOrNil(const char* script);
|
expected<float> testLuaReturnsNumberOrNil(const char* script);
|
||||||
float testLuaReturnsNumber(const char* script);
|
float testLuaReturnsNumber(const char* script);
|
||||||
int testLuaReturnsInteger(const char* script);
|
int testLuaReturnsInteger(const char* script);
|
||||||
|
void testLuaExecString(const char* script);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
|
|
||||||
#include "efifeatures.h"
|
#include "efifeatures.h"
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
#include "can_msg_tx.h"
|
||||||
|
|
||||||
#if EFI_CAN_SUPPORT
|
#if EFI_CAN_SUPPORT
|
||||||
#include "can.h"
|
#include "can.h"
|
||||||
#include "can_msg_tx.h"
|
|
||||||
#include "engine_configuration.h"
|
#include "engine_configuration.h"
|
||||||
|
|
||||||
EXTERN_CONFIG
|
EXTERN_CONFIG
|
||||||
|
@ -43,7 +43,7 @@ CanTxMessage::CanTxMessage(uint32_t eid, uint8_t dlc, bool isExtended) {
|
||||||
CAN_SID(m_frame) = eid;
|
CAN_SID(m_frame) = eid;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame.DLC = dlc;
|
setDlc(dlc);
|
||||||
|
|
||||||
memset(m_frame.data8, 0, sizeof(m_frame.data8));
|
memset(m_frame.data8, 0, sizeof(m_frame.data8));
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,10 @@ CanTxMessage::~CanTxMessage() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanTxMessage::setDlc(uint8_t dlc) {
|
||||||
|
m_frame.DLC = dlc;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t& CanTxMessage::operator[](size_t index) {
|
uint8_t& CanTxMessage::operator[](size_t index) {
|
||||||
return m_frame.data8[index];
|
return m_frame.data8[index];
|
||||||
}
|
}
|
||||||
|
@ -86,4 +90,20 @@ void CanTxMessage::setBit(size_t byteIdx, size_t bitIdx) {
|
||||||
m_frame.data8[byteIdx] |= 1 << bitIdx;
|
m_frame.data8[byteIdx] |= 1 << bitIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
CanTxMessage::CanTxMessage(uint32_t /*eid*/, uint8_t /*dlc*/, bool /*isExtended*/) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CanTxMessage::~CanTxMessage() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t& CanTxMessage::operator[](size_t index) {
|
||||||
|
return m_data8[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanTxMessage::setDlc(uint8_t) { }
|
||||||
|
|
||||||
#endif // EFI_CAN_SUPPORT
|
#endif // EFI_CAN_SUPPORT
|
||||||
|
|
|
@ -56,9 +56,13 @@ public:
|
||||||
*/
|
*/
|
||||||
void setBit(size_t byteIdx, size_t bitIdx);
|
void setBit(size_t byteIdx, size_t bitIdx);
|
||||||
|
|
||||||
|
void setDlc(uint8_t dlc);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#if EFI_CAN_SUPPORT
|
#if EFI_CAN_SUPPORT
|
||||||
CANTxFrame m_frame;
|
CANTxFrame m_frame;
|
||||||
|
#else // not EFI_CAN_SUPPORT
|
||||||
|
uint8_t m_data8[8];
|
||||||
#endif // EFI_CAN_SUPPORT
|
#endif // EFI_CAN_SUPPORT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -13,12 +13,12 @@ HW_LAYER_DRIVERS_CORE = \
|
||||||
HW_LAYER_DRIVERS_CORE_CPP = \
|
HW_LAYER_DRIVERS_CORE_CPP = \
|
||||||
$(DRIVERS_DIR)/gpio/core.cpp \
|
$(DRIVERS_DIR)/gpio/core.cpp \
|
||||||
$(DRIVERS_DIR)/i2c/i2c_bb.cpp \
|
$(DRIVERS_DIR)/i2c/i2c_bb.cpp \
|
||||||
|
$(DRIVERS_DIR)/can/can_msg_tx.cpp \
|
||||||
|
|
||||||
HW_LAYER_DRIVERS =
|
HW_LAYER_DRIVERS =
|
||||||
|
|
||||||
HW_LAYER_DRIVERS_CPP = \
|
HW_LAYER_DRIVERS_CPP = \
|
||||||
$(DRIVERS_DIR)/can/can_hw.cpp \
|
$(DRIVERS_DIR)/can/can_hw.cpp \
|
||||||
$(DRIVERS_DIR)/can/can_msg_tx.cpp \
|
|
||||||
$(DRIVERS_DIR)/serial/serial_hw.cpp \
|
$(DRIVERS_DIR)/serial/serial_hw.cpp \
|
||||||
$(DRIVERS_DIR)/gpio/tle6240.cpp \
|
$(DRIVERS_DIR)/gpio/tle6240.cpp \
|
||||||
$(DRIVERS_DIR)/gpio/tle8888.cpp \
|
$(DRIVERS_DIR)/gpio/tle8888.cpp \
|
||||||
|
|
|
@ -36,3 +36,41 @@ TEST(LuaHooks, Table3d) {
|
||||||
setTable(config->fsioTable2, (uint8_t)14);
|
setTable(config->fsioTable2, (uint8_t)14);
|
||||||
EXPECT_EQ(testLuaReturnsNumber(tableTest), 14);
|
EXPECT_EQ(testLuaReturnsNumber(tableTest), 14);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(LuaHooks, CanTxChannel) {
|
||||||
|
// channel 1 valid
|
||||||
|
EXPECT_NO_THROW(testLuaExecString("txCan(1, 0, 0, {0})"));
|
||||||
|
|
||||||
|
// channel 0 invalid
|
||||||
|
EXPECT_ANY_THROW(testLuaExecString("txCan(0, 0, 0, {0})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LuaHooks, CanTxId) {
|
||||||
|
// std ID ok
|
||||||
|
EXPECT_NO_THROW(testLuaExecString("txCan(1, 2047, 0, {0})"));
|
||||||
|
// std ID too high
|
||||||
|
EXPECT_ANY_THROW(testLuaExecString("txCan(1, 2048, 0, {0})"));
|
||||||
|
|
||||||
|
// ext ID ok
|
||||||
|
EXPECT_NO_THROW(testLuaExecString("txCan(1, 536870911, 1, {0})"));
|
||||||
|
// ext ID too high
|
||||||
|
EXPECT_ANY_THROW(testLuaExecString("txCan(1, 536870912, 1, {0})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(LuaHooks, CanTxDataLength) {
|
||||||
|
// valid: DLC = 0
|
||||||
|
EXPECT_NO_THROW(testLuaExecString("txCan(1, 0, 0, {})"));
|
||||||
|
// valid: DLC = 1
|
||||||
|
EXPECT_NO_THROW(testLuaExecString("txCan(1, 0, 0, {0})"));
|
||||||
|
// valid: DLC = 8
|
||||||
|
EXPECT_NO_THROW(testLuaExecString("txCan(1, 0, 0, {1, 2, 3, 4, 5, 6, 7, 8})"));
|
||||||
|
|
||||||
|
// invalid: DLC = 9
|
||||||
|
EXPECT_ANY_THROW(testLuaExecString("txCan(1, 0, 0, {1, 2, 3, 4, 5, 6, 7, 8, 9})"));
|
||||||
|
|
||||||
|
// invalid: is a table, but contains a not-number
|
||||||
|
EXPECT_ANY_THROW(testLuaExecString("txCan(1, 0, 0, {1, 2, 3, 'hello', 5, 6})"));
|
||||||
|
|
||||||
|
// invalid: not a table
|
||||||
|
EXPECT_ANY_THROW(testLuaExecString("txCan(1, 0, 0, 26)"));
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue