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);
|
||||
}
|
||||
|
||||
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_LUA
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "airmass.h"
|
||||
#include "lua_airmass.h"
|
||||
#include "pwm_generator_logic.h"
|
||||
#include "can_msg_tx.h"
|
||||
|
||||
// Some functions lean on existing FSIO implementation
|
||||
#include "fsio_impl.h"
|
||||
|
@ -67,6 +68,62 @@ static int lua_table3d(lua_State* l) {
|
|||
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;
|
||||
|
||||
AirmassModelBase& getLuaAirmassModel() {
|
||||
|
@ -235,6 +292,7 @@ void configureRusefiLuaHooks(lua_State* l) {
|
|||
lua_register(l, "getSensorRaw", lua_getSensorRaw);
|
||||
lua_register(l, "hasSensor", lua_hasSensor);
|
||||
lua_register(l, "table3d", lua_table3d);
|
||||
lua_register(l, "txCan", lua_txCan);
|
||||
|
||||
#if !EFI_UNIT_TEST
|
||||
lua_register(l, "startPwm", lua_startPwm);
|
||||
|
|
|
@ -10,4 +10,5 @@ void startLua();
|
|||
expected<float> testLuaReturnsNumberOrNil(const char* script);
|
||||
float testLuaReturnsNumber(const char* script);
|
||||
int testLuaReturnsInteger(const char* script);
|
||||
void testLuaExecString(const char* script);
|
||||
#endif
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
#include "efifeatures.h"
|
||||
#include "global.h"
|
||||
#include "can_msg_tx.h"
|
||||
|
||||
#if EFI_CAN_SUPPORT
|
||||
#include "can.h"
|
||||
#include "can_msg_tx.h"
|
||||
#include "engine_configuration.h"
|
||||
|
||||
EXTERN_CONFIG
|
||||
|
@ -43,7 +43,7 @@ CanTxMessage::CanTxMessage(uint32_t eid, uint8_t dlc, bool isExtended) {
|
|||
CAN_SID(m_frame) = eid;
|
||||
}
|
||||
|
||||
m_frame.DLC = dlc;
|
||||
setDlc(dlc);
|
||||
|
||||
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) {
|
||||
return m_frame.data8[index];
|
||||
}
|
||||
|
@ -86,4 +90,20 @@ void CanTxMessage::setBit(size_t byteIdx, size_t 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
|
||||
|
|
|
@ -56,9 +56,13 @@ public:
|
|||
*/
|
||||
void setBit(size_t byteIdx, size_t bitIdx);
|
||||
|
||||
void setDlc(uint8_t dlc);
|
||||
|
||||
protected:
|
||||
#if EFI_CAN_SUPPORT
|
||||
CANTxFrame m_frame;
|
||||
#else // not EFI_CAN_SUPPORT
|
||||
uint8_t m_data8[8];
|
||||
#endif // EFI_CAN_SUPPORT
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,12 +13,12 @@ HW_LAYER_DRIVERS_CORE = \
|
|||
HW_LAYER_DRIVERS_CORE_CPP = \
|
||||
$(DRIVERS_DIR)/gpio/core.cpp \
|
||||
$(DRIVERS_DIR)/i2c/i2c_bb.cpp \
|
||||
$(DRIVERS_DIR)/can/can_msg_tx.cpp \
|
||||
|
||||
HW_LAYER_DRIVERS =
|
||||
|
||||
HW_LAYER_DRIVERS_CPP = \
|
||||
$(DRIVERS_DIR)/can/can_hw.cpp \
|
||||
$(DRIVERS_DIR)/can/can_msg_tx.cpp \
|
||||
$(DRIVERS_DIR)/serial/serial_hw.cpp \
|
||||
$(DRIVERS_DIR)/gpio/tle6240.cpp \
|
||||
$(DRIVERS_DIR)/gpio/tle8888.cpp \
|
||||
|
|
|
@ -36,3 +36,41 @@ TEST(LuaHooks, Table3d) {
|
|||
setTable(config->fsioTable2, (uint8_t)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