Skip to content

Commit

Permalink
improved documentation, extracted duplicated code, fixed headers CAN
Browse files Browse the repository at this point in the history
  • Loading branch information
SpieringsAE committed May 16, 2024
1 parent 7c644ad commit 5b99849
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 120 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
.vscode/settings.json
.vscode*
crank_files/
*.slxc
*.slxc
*.autosave
61 changes: 54 additions & 7 deletions blockset/blocks/can_common.tlc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
%<LibAddToCommonIncludes("<fcntl.h>")>
%<LibAddToCommonIncludes("<errno.h>")>
%<LibAddToCommonIncludes("unistd.h")>
%if !SLibCodeGenForSim()
%<LibAddToCommonIncludes("can_message.h")>
%endif
%endfunction

%function SLibCodeGenForSim() void
Expand All @@ -70,15 +73,59 @@
%endif
%endfunction

%function CommonBlockTypeSetup(block, system) void
%if EXISTS("_DONE_COMMON_BLOCK_TYPE_SETUP_") == 0
%assign _DONE_COMMON_BLOCK_TYPE_SETUP_ = 1
%if !SLibCodeGenForSim()
%function CreateCanSocket(CanNum) void
%assign can_socket = "::can_%<CanNum>"
%if EXISTS(%<can_socket>) == 0
%% Mark the socket as created
%assign %<can_socket> = 1
%openfile tmpBuf
int can_%<CanNum>;
%closefile tmpBuf

%<LibAddToCommonIncludes("can_message.h")>
%<LibSetSourceFileSection(LibGetModelDotCFile(), "UserTop", tmpBuf)>
%endif
%endfunction

%function InitCanSocket(CanNum) Output
%assign can_socket = "::can_%<CanNum>_init"
%if EXISTS(%<can_socket>) == 0
%% Mark the socket as initialized
%assign %<can_socket> = 1
{
struct sockaddr_can addr;
struct ifreq ifr;
char* ifname = "can%<CanNum - 1>";

%endif
%endif
can_%<CanNum> = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (can_%<CanNum> == -1) {
printf("CAN socket create error.\n");
}
%% Socket should never block, or it will hold up the model
if(fcntl(can_%<CanNum>, F_SETFL, O_NONBLOCK) < 0) {
printf("CAN socket set O_NONBLOCK error.\n");
}
memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) -1);
if (ioctl(can_%<CanNum>, SIOCGIFINDEX, &ifr) < 0) {
printf("CAN socket ioctl SIOCGIFINDEX error.\n");
}
addr.can_ifindex = ifr.ifr_ifindex;

if (bind(can_%<CanNum>, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
printf("CAN socket bind error.\n");
}
printf("opening %s\n", ifname);
}
%endif
%endfunction

%function CloseCanSocket(CanNum) Output
%assign can_socket = "::can_%<CanNum>_term"
%if EXISTS(%<can_socket>) == 0
%assign %<can_socket> = 1

close(can_%<CanNum>);
%endif
%endfunction
%% [EOF]
4 changes: 2 additions & 2 deletions blockset/blocks/sfcn_can_receive_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@


/* Adopted for use by GOcontroll 2024 http://www.gocontroll.com All rights reserved
* \file sfcn_can_receive.c
* \file sfcn_can_receive_v2.c
* \brief matlab sfunction for receiving CAN messages on the Moduline Controllers
*/

Expand All @@ -55,7 +55,7 @@
#include "sfun_can_util.h"
#include "simstruc.h"

#define PARAM_NAME_MODULE_ID "module_id"
#define PARAM_NAME_MODULE_ID "module_id" //CAN bus number starting at 1

/** Identifiers of the block parameters */
enum params{
Expand Down
88 changes: 32 additions & 56 deletions blockset/blocks/sfcn_can_receive_v2.tlc
Original file line number Diff line number Diff line change
Expand Up @@ -43,119 +43,95 @@


%% Adopted for use by GOcontroll 2024 http://www.gocontroll.com All right reserved
%% File : sfcn_can_receive.tlc
%% Brief : help functions for the can tlcs
%% File : sfcn_can_receive_v2.tlc
%% Brief : tlc file for generating code to receive CAN messages on the Moduline Controllers

%implements sfcn_can_receive_v2 "C"

%include "can_common.tlc"

%% Function: BlockTypeSetup ====================================================
%function BlockTypeSetup(block, system) void
%<CommonBlockTypeSetup(block, system)>
%<CANCommonBlockTypeSetup()>
%endfunction

%% Function: BlockInstanceSetup ================================================
%function BlockInstanceSetup(block, system) void

%assign module_id_par = LibBlockParameterValue(module_id, 0)

%% There can only be one receive block per socket, check, error if one already exists
%assign can_recv_socket = "::can_%<module_id_par>_recv"
%if EXISTS(%<can_recv_socket>) == 1
%assign error = "2 or more CAN receive blocks are listening on CAN%<module_id_par>, this is not allowed"
%<LibBlockReportError(block, error)>
%else
%% No existing receive block found for this socket, so register it as occupied so the next one can fail
%assign %<can_recv_socket> = 1
%endif

%assign can_socket = "::can_%<module_id_par>"
%if EXISTS(%<can_socket>) == 0
%assign %<can_socket> = 1
%openfile tmpBuf
int can_%<module_id_par>;
%closefile tmpBuf

%<LibSetSourceFileSection(LibGetModelDotCFile(), "UserTop", tmpBuf)>
%endif
%% Check if the socket for this bus is already there, if not create it
%<CreateCanSocket(module_id_par)>
%endfunction

%% Function: Start =============================================================
%function Start(block, system) Output
%assign module_id_par = LibBlockParameterValue(module_id, 0)

%assign can_socket = "::can_%<module_id_par>_init"
%if EXISTS(%<can_socket>) == 0
%assign %<can_socket> = 1
{
struct sockaddr_can addr;
struct ifreq ifr;
char* ifname = "can%<module_id_par - 1>";

can_%<module_id_par> = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (can_%<module_id_par> == -1) {
printf("CAN socket create error.\n");
}
if(fcntl(can_%<module_id_par>, F_SETFL, O_NONBLOCK) < 0) {
printf("CAN socket set O_NONBLOCK error.\n");
}
memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) -1);
if (ioctl(can_%<module_id_par>, SIOCGIFINDEX, &ifr) < 0) {
printf("CAN socket ioctl SIOCGIFINDEX error.\n");
}
addr.can_ifindex = ifr.ifr_ifindex;

if (bind(can_%<module_id_par>, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
printf("CAN socket bind error.\n");
}
printf("opening %s\n", ifname);
}
%endif
%% Initialize the socket if it hasn't already been done
%<InitCanSocket(module_id_par)>
%endfunction

%% Function: Outputs ===========================================================
%function Outputs(block, system) Output

%if !SLibCodeGenForSim()
%assign module_id_par = LibBlockParameterValue(module_id, 0)
%assign message = LibBlockOutputSignal(1, "", "", 1)
%assign module_id_par = LibBlockParameterValue(module_id, 0)
%% message will be of the type CAN_MESSAGE, run this command in the matlab console to find the definition:
%% edit(fullfile(matlabroot, 'toolbox','shared','can','src','scanutil','can_message.h'));
%assign message = LibBlockOutputSignal(1, "", "", 1)

{
struct can_frame sc_frame;
int ret;
int dlc;
{
struct can_frame sc_frame;
int ret;
int dlc;
%% Drain the sockets buffer and decode these messages
while ((ret = recv(can_%<module_id_par>, &sc_frame, sizeof(sc_frame), 0)) > 0) {
%% Invalid message received
if (ret < sizeof(sc_frame)) {
continue;
}

while ((ret = recv(can_%<module_id_par>, &sc_frame, sizeof(sc_frame), 0)) > 0) {
if (ret < sizeof(sc_frame)) {
continue;
} else {
dlc = sc_frame.can_dlc;
%% dlc cant be larger than 8
if (dlc > 8)
dlc = 8;

%%Receive CAN_MESSAGE
%% Receive CAN_MESSAGE
%<message>.Length = dlc;
%<message>.ID = sc_frame.can_id & CAN_EFF_MASK;
%% Check message flags
%<message>.Extended = sc_frame.can_id & CAN_EFF_FLAG ? 1 : 0;
%<message>.Remote = sc_frame.can_id & CAN_RTR_FLAG ? 1 : 0;

%%Write all bytes in one go
*(uint64_t *)&%<message>.Data[0]= *(uint64_t *)&sc_frame.data[0];

%% Call a function to process the received message via function-call subsystem
%% Do a function call for every received message
%foreach callIdx = NumSFcnSysOutputCalls
%if LibIsEqual(SFcnSystemOutputCall[callIdx].BlockToCall,"unconnected")
%continue
%endif
%% call the downstream system
%<LibBlockExecuteFcnCall(block, callIdx)>\
%endforeach

}
}
}
%endif
%endfunction

%function Terminate(block, system) Output
%assign module_id_par = LibBlockParameterValue(module_id, 0)
%<CloseCanSocket(module_id_par)>
%endfunction

%% [EOF]
7 changes: 6 additions & 1 deletion blockset/blocks/sfcn_can_send_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,19 @@ Relevant demos:
...
*/

/* Adopted for use by GOcontroll 2024 http://www.gocontroll.com All rights reserved
* \file sfcn_can_send_v2.c
* \brief matlab sfunction for sending CAN messages on the Moduline Controllers
*/


#define S_FUNCTION_NAME sfcn_can_send_v2
#include "header.c"
#include <stdio.h>
#include "sfun_can_util.h"
#include "simstruc.h"

#define PARAM_NAME_MODULE_ID "module_id"
#define PARAM_NAME_MODULE_ID "module_id" //CAN bus number starting at 1

/** Identifier of the input */
enum input {
Expand Down
65 changes: 12 additions & 53 deletions blockset/blocks/sfcn_can_send_v2.tlc
Original file line number Diff line number Diff line change
Expand Up @@ -43,81 +43,46 @@


%% Adopted for use by GOcontroll 2024 http://www.gocontroll.com All right reserved
%% File : sfcn_can_send.tlc
%% Brief : help functions for the can tlcs
%% File : sfcn_can_send_v2.tlc
%% Brief : tlc file for generating code to send CAN messages on the Moduline Controllers

%implements sfcn_can_send_v2 "C"

%include "can_common.tlc"

%% Function: BlockTypeSetup ====================================================
%function BlockTypeSetup(block, system) void
%<CommonBlockTypeSetup(block, system)>
%<CANCommonBlockTypeSetup()>
%endfunction

%% Function: BlockInstanceSetup ================================================
%function BlockInstanceSetup(block, system) void
%assign module_id_par = LibBlockParameterValue(module_id, 0)

%assign can_socket = "::can_%<module_id_par>"
%if EXISTS(%<can_socket>) == 0
%assign %<can_socket> = 1
%openfile tmpBuf
int can_%<module_id_par>;
%closefile tmpBuf

%<LibSetSourceFileSection(LibGetModelDotCFile(), "UserTop", tmpBuf)>
%endif
%% Check if the socket for this bus is already there, if not create it
%<CreateCanSocket(module_id_par)>
%endfunction

%% Function: Start =============================================================
%function Start(block, system) Output
%assign module_id_par = LibBlockParameterValue(module_id, 0)

%assign can_socket = "::can_%<module_id_par>_init"
%if EXISTS(%<can_socket>) == 0
%assign %<can_socket> = 1
{
struct sockaddr_can addr;
struct ifreq ifr;
char* ifname = "can%<module_id_par - 1>";

can_%<module_id_par> = socket(PF_CAN, SOCK_RAW, CAN_RAW);
if (can_%<module_id_par> == -1) {
printf("CAN socket create error.\n");
}
if(fcntl(can_%<module_id_par>, F_SETFL, O_NONBLOCK) < 0) {
printf("CAN socket set O_NONBLOCK error.\n");
}
memset(&addr, 0, sizeof(addr));
addr.can_family = AF_CAN;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name) -1);
if (ioctl(can_%<module_id_par>, SIOCGIFINDEX, &ifr) < 0) {
printf("CAN socket ioctl SIOCGIFINDEX error.\n");
}
addr.can_ifindex = ifr.ifr_ifindex;

if (bind(can_%<module_id_par>, (struct sockaddr *)(void*)&addr, sizeof(addr)) < 0) {
printf("CAN socket bind error.\n");
}
printf("opening %s\n", ifname);
}
%endif
%% Initialize the socket if it hasn't already been done
%<InitCanSocket(module_id_par)>
%endfunction

%% Function: Outputs ===========================================================
%function Outputs(block, system) Output
%if !SLibCodeGenForSim()
%assign message = LibBlockInputSignal(0, "", "", 0)
%% message will be of the type CAN_MESSAGE, run this command in the matlab console to find the definition:
%% edit(fullfile(matlabroot, 'toolbox','shared','can','src','scanutil','can_message.h'));
%assign module_id_par = LibBlockParameterValue(module_id, 0)

{
struct can_frame sc_frame;

%%Transmit CAN_MESSAGE
%% Transmit CAN_MESSAGE
sc_frame.can_dlc = %<message>.Length;

%%Write all bytes in one go
*(uint64_t *)&sc_frame.data[0]= *(uint64_t *)&%<message>.Data[0];

Expand All @@ -133,16 +98,10 @@
%endif
%endfunction

%% Function: Outputs ===========================================================
%% Function: Terminate ===========================================================
%function Terminate(block, system) Output
%assign module_id_par = LibBlockParameterValue(module_id, 0)

%assign can_socket = "::can_%<module_id_par>_term"
%if EXISTS(%<can_socket>) == 0
%assign %<can_socket> = 1

close(can_%<module_id_par>);
%endif
%<CloseCanSocket(module_id_par)>
%endfunction

%% [EOF]

0 comments on commit 5b99849

Please sign in to comment.