rusEFI
The most advanced open source ECU
Functions | Variables
lua_can_rx.cpp File Reference

Functions

void processLuaCan (const size_t busIndex, const CANRxFrame &frame)
 
static void lua_createtable_noGC (lua_State *L, int narray)
 
static void handleCanFrame (LuaHandle &ls, CanFrameData *data)
 
static bool doOneLuaCanRx (LuaHandle &ls)
 
int doLuaCanRx (LuaHandle &ls)
 
void initLuaCanRx ()
 

Variables

static constexpr size_t canFrameCount = 32
 
static CanFrameData canFrames [canFrameCount]
 
static chibios_rt::Mailbox< CanFrameData *, canFrameCountfreeBuffers
 
static chibios_rt::Mailbox< CanFrameData *, canFrameCountfilledBuffers
 

Function Documentation

◆ doLuaCanRx()

int doLuaCanRx ( LuaHandle ls)

Definition at line 159 of file lua_can_rx.cpp.

159  {
161  int counter = 0;
162  // While it processed a frame, continue checking
163  while (doOneLuaCanRx(ls)) {
164  counter++;
165  }
166  return counter;
167 }
static bool doOneLuaCanRx(LuaHandle &ls)
Definition: lua_can_rx.cpp:131
@ LuaAllCanRxFunction

Referenced by runOneLua().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ doOneLuaCanRx()

static bool doOneLuaCanRx ( LuaHandle ls)
static

Definition at line 131 of file lua_can_rx.cpp.

131  {
133  CanFrameData* data;
134 
135  msg_t msg = filledBuffers.fetch(&data, TIME_IMMEDIATE);
136 
137  if (msg == MSG_TIMEOUT) {
138  // No new CAN messages rx'd, nothing more to do.
139  return false;
140  }
141 
142  if (msg != MSG_OK) {
143  // Message was otherwise not OK
144  // TODO: what do here?
145  return false;
146  }
147 
148  // We've accepted the frame, process it in Lua.
149  handleCanFrame(ls, data);
150 
151  // We're done, return this frame to the free list
152  msg = freeBuffers.post(data, TIME_IMMEDIATE);
153  efiAssert(ObdCode::OBD_PCM_Processor_Fault, msg == MSG_OK, "lua can post to free buffer fail", false);
154 
155  // We processed a frame so we should check again
156  return true;
157 }
static chibios_rt::Mailbox< CanFrameData *, canFrameCount > filledBuffers
Definition: lua_can_rx.cpp:27
static chibios_rt::Mailbox< CanFrameData *, canFrameCount > freeBuffers
Definition: lua_can_rx.cpp:25
static void handleCanFrame(LuaHandle &ls, CanFrameData *data)
Definition: lua_can_rx.cpp:80
@ OBD_PCM_Processor_Fault
@ LuaOneCanRxFunction

Referenced by doLuaCanRx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleCanFrame()

static void handleCanFrame ( LuaHandle ls,
CanFrameData *  data 
)
static

Definition at line 80 of file lua_can_rx.cpp.

80  {
82  if (data->Callback == NO_CALLBACK) {
83  // No callback, use catch-all function
84  lua_getglobal(ls, "onCanRx");
85  } else {
86  // Push the specified callback on to the stack
87  lua_rawgeti(ls, LUA_REGISTRYINDEX, data->Callback);
88  }
89 
90  if (lua_isnil(ls, -1)) {
91  // no rx function, ignore
92  efiPrintf("LUA CAN rx missing function onCanRx");
93  lua_settop(ls, 0);
94  return;
95  }
96 
97  auto dlc = data->Frame.DLC;
98 
99  // Push bus, ID and DLC
100  lua_pushinteger(ls, data->BusIndex);
101  lua_pushinteger(ls, CAN_ID(data->Frame));
102  lua_pushinteger(ls, dlc);
103 
105  // todo: https://github.com/rusefi/rusefi/issues/6041
106  lua_getglobal(ls, "global_can_data");
107  } else {
108  // Build table for data, custom implementation without explicit GC but still garbage
109  lua_createtable_noGC(ls, dlc);
110  }
111  for (size_t i = 0; i < dlc; i++) {
112  lua_pushinteger(ls, data->Frame.data8[i]);
113 
114  // index is i+1 because Lua "arrays" (tables) are 1-indexed
115  lua_rawseti(ls, -2, i + 1);
116  }
117 
118  // Perform the actual function call
119  int status = lua_pcall(ls, 4, 0, 0);
120 
121  if (0 != status) {
122  // error calling CAN rx hook function
123  auto errMsg = lua_tostring(ls, -1);
124  efiPrintf("LUA CAN RX error %s", errMsg);
125  lua_pop(ls, 1);
126  }
127 
128  lua_settop(ls, 0);
129 }
static void lua_createtable_noGC(lua_State *L, int narray)
Definition: lua_can_rx.cpp:65
@ LuaOneCanRxCallback
engine_configuration_s * engineConfiguration

Referenced by doOneLuaCanRx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initLuaCanRx()

void initLuaCanRx ( )

Definition at line 169 of file lua_can_rx.cpp.

169  {
170  // Push all CAN frames in to the free buffer
171  for (size_t i = 0; i < canFrameCount; i++) {
172  freeBuffers.post(&canFrames[i], TIME_INFINITE);
173  }
174 }
static CanFrameData canFrames[canFrameCount]
Definition: lua_can_rx.cpp:23
static constexpr size_t canFrameCount
Definition: lua_can_rx.cpp:22

Referenced by startLua().

Here is the caller graph for this function:

◆ lua_createtable_noGC()

static void lua_createtable_noGC ( lua_State *  L,
int  narray 
)
static

Definition at line 65 of file lua_can_rx.cpp.

65  {
66  Table *t;
67  lua_lock(L);
68  t = luaH_new(L);
69  sethvalue2s(L, L->top, t);
70  api_incr_top(L);
71  luaH_resize(L, t, narray, 0);
72 
73  // This line is commented out - no need to do a GC every time in
74  // this hot path when we'll do it shortly and have plenty of memory available.
75  // luaC_checkGC(L);
76 
77  lua_unlock(L);
78 }

Referenced by handleCanFrame().

Here is the caller graph for this function:

◆ processLuaCan()

void processLuaCan ( const size_t  busIndex,
const CANRxFrame frame 
)

Definition at line 29 of file lua_can_rx.cpp.

29  {
30  auto filter = getFilterForId(busIndex, CAN_ID(frame));
31 
32  // Filter the frame if we aren't listening for it
33  if (!filter) {
34  return;
35  }
36 
37  CanFrameData* frameBuffer;
38  msg_t msg;
39 
40  {
41  // Acquire a buffer under lock
42  chibios_rt::CriticalSectionLocker csl;
43  msg = freeBuffers.fetchI(&frameBuffer);
44  }
45 
46  if (msg != MSG_OK) {
47  // all buffers are already in use, this frame will be dropped!
48  // TODO: warn the user
49  return;
50  }
51 
52  // Copy the frame in to the buffer
53  frameBuffer->BusIndex = busIndex;
54  frameBuffer->Frame = frame;
55  frameBuffer->Callback = filter->Callback;
56 
57  {
58  // Push the frame in to the queue under lock
59  chibios_rt::CriticalSectionLocker csl;
60  filledBuffers.postI(frameBuffer);
61  }
62 }
CanFilter * getFilterForId(size_t busIndex, int Id)
Definition: can_filter.cpp:10

Referenced by processCanRxMessage().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ canFrameCount

constexpr size_t canFrameCount = 32
staticconstexpr

Definition at line 22 of file lua_can_rx.cpp.

Referenced by initLuaCanRx().

◆ canFrames

CanFrameData canFrames[canFrameCount]
static

Definition at line 23 of file lua_can_rx.cpp.

Referenced by initLuaCanRx().

◆ filledBuffers

chibios_rt::Mailbox<CanFrameData*, canFrameCount> filledBuffers
static

Definition at line 27 of file lua_can_rx.cpp.

Referenced by doOneLuaCanRx(), GetToothLoggerBufferImpl(), and processLuaCan().

◆ freeBuffers

chibios_rt::Mailbox<CanFrameData*, canFrameCount> freeBuffers
static

Go to the source code of this file.