From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- Master/Real-Time Systems/mki/.cproject | 143 +++++ Master/Real-Time Systems/mki/.metadata/.log | 19 + .../.root/.indexes/properties.version | 1 + .../.settings/org.eclipse.team.cvs.ui.prefs | 3 + .../.settings/org.eclipse.team.ui.prefs | 3 + .../.settings/org.eclipse.ui.ide.prefs | 6 + .../usagedata.csv | 63 ++ .../org.eclipse.ui.ide/dialog_settings.xml | 5 + .../org.eclipse.ui.workbench/dialog_settings.xml | 7 + .../org.eclipse.ui.workbench/workbench.xml | 175 ++++++ Master/Real-Time Systems/mki/.project | 78 +++ Master/Real-Time Systems/mki/Makefile | 10 + Master/Real-Time Systems/mki/src/libcanio.cpp | 680 +++++++++++++++++++++ Master/Real-Time Systems/mki/src/libcanio.h | 81 +++ Master/Real-Time Systems/mki/src/mki.cpp | 439 +++++++++++++ Master/Real-Time Systems/mki/src/mki.h | 86 +++ Master/Real-Time Systems/mki/test/mkidemo.cpp | 130 ++++ 17 files changed, 1929 insertions(+) create mode 100644 Master/Real-Time Systems/mki/.cproject create mode 100644 Master/Real-Time Systems/mki/.metadata/.log create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.epp.usagedata.recording/usagedata.csv create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml create mode 100644 Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml create mode 100644 Master/Real-Time Systems/mki/.project create mode 100644 Master/Real-Time Systems/mki/Makefile create mode 100644 Master/Real-Time Systems/mki/src/libcanio.cpp create mode 100644 Master/Real-Time Systems/mki/src/libcanio.h create mode 100644 Master/Real-Time Systems/mki/src/mki.cpp create mode 100644 Master/Real-Time Systems/mki/src/mki.h create mode 100644 Master/Real-Time Systems/mki/test/mkidemo.cpp (limited to 'Master/Real-Time Systems/mki') diff --git a/Master/Real-Time Systems/mki/.cproject b/Master/Real-Time Systems/mki/.cproject new file mode 100644 index 0000000..ad14f97 --- /dev/null +++ b/Master/Real-Time Systems/mki/.cproject @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Master/Real-Time Systems/mki/.metadata/.log b/Master/Real-Time Systems/mki/.metadata/.log new file mode 100644 index 0000000..d6ddf32 --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.log @@ -0,0 +1,19 @@ + +!ENTRY org.eclipse.ui.ide 4 4 2010-11-12 16:45:15.094 +!MESSAGE Problems saving workspace + +!ENTRY org.eclipse.ui.ide 4 1 2010-11-12 16:45:15.105 +!MESSAGE Problems occurred while trying to save the state of the workbench. +!SUBENTRY 1 org.eclipse.core.resources 4 568 2010-11-12 16:45:15.105 +!MESSAGE Could not write workspace metadata '/home/user/Desktop/mki/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree'. +!STACK 0 +java.io.FileNotFoundException: /home/user/Desktop/mki/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree (No such file or directory) + at java.io.FileOutputStream.open(Native Method) + at java.io.FileOutputStream.(FileOutputStream.java:209) + at java.io.FileOutputStream.(FileOutputStream.java:160) + at org.eclipse.core.internal.localstore.SafeFileOutputStream.(SafeFileOutputStream.java:46) + at org.eclipse.core.internal.resources.SaveManager.saveTree(SaveManager.java:1326) + at org.eclipse.core.internal.resources.SaveManager.save(SaveManager.java:1112) + at org.eclipse.core.internal.resources.Workspace.save(Workspace.java:2006) + at org.eclipse.ui.internal.ide.application.IDEWorkbenchAdvisor$5.run(IDEWorkbenchAdvisor.java:502) + at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121) diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version new file mode 100644 index 0000000..6b2aaa7 --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs new file mode 100644 index 0000000..ea3063e --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs @@ -0,0 +1,3 @@ +#Fri Nov 12 16:45:15 CET 2010 +pref_first_startup=false +eclipse.preferences.version=1 diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs new file mode 100644 index 0000000..f3d3b3f --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs @@ -0,0 +1,3 @@ +#Fri Nov 12 16:45:15 CET 2010 +eclipse.preferences.version=1 +org.eclipse.team.ui.first_time=false diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs new file mode 100644 index 0000000..c7e39dd --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -0,0 +1,6 @@ +#Fri Nov 12 16:45:15 CET 2010 +eclipse.preferences.version=1 +tipsAndTricks=true +platformState=1289576175261 +quickStart=false +PROBLEMS_FILTERS_MIGRATE=true diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.epp.usagedata.recording/usagedata.csv b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.epp.usagedata.recording/usagedata.csv new file mode 100644 index 0000000..8f76741 --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.epp.usagedata.recording/usagedata.csv @@ -0,0 +1,63 @@ +what,kind,bundleId,bundleVersion,description,time +executed,command,org.eclipse.ui,3.6.1.M20100826-1330,"org.eclipse.ui.file.import",1289576365533 +activated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576365581 +deactivated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576603046 +activated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576630114 +deactivated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576643455 +activated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576647142 +deactivated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576658732 +executed,command,org.eclipse.ui,3.6.1.M20100826-1330,"org.eclipse.ui.newWizard",1289576702282 +activated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576702317 +deactivated,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576710892 +closed,workbench,org.eclipse.ui.workbench,3.6.1.M20100826-1330,"",1289576713030 +error,log,,,"Problems saving workspace",1289576715104 +error,log,,,"Problems occurred while trying to save the state of the workbench.",1289576715107 +started,bundle,org.eclipse.compare,3.5.100.I20100526-0800,"org.eclipse.compare",1289576715197 +stopped,bundle,org.eclipse.cdt.debug.mi.ui,6.1.0.201009141542,"org.eclipse.cdt.debug.mi.ui",1289576715325 +stopped,bundle,org.eclipse.cdt.debug.mi.core,7.0.1.201009141542,"org.eclipse.cdt.debug.mi.core",1289576715325 +stopped,bundle,org.eclipse.cdt.debug.ui.memory.memorybrowser,1.2.0.201009141542,"org.eclipse.cdt.debug.ui.memory.memorybrowser",1289576715325 +stopped,bundle,org.eclipse.cdt.debug.ui.memory.search,1.2.0.201009141542,"org.eclipse.cdt.debug.ui.memory.search",1289576715325 +stopped,bundle,org.eclipse.cdt.dsf.gdb.ui,2.1.0.201009141542,"org.eclipse.cdt.dsf.gdb.ui",1289576715325 +stopped,bundle,org.eclipse.cdt.dsf.ui,2.1.1.201009141542,"org.eclipse.cdt.dsf.ui",1289576715325 +stopped,bundle,org.eclipse.cdt.gdb.ui,7.0.0.201009141542,"org.eclipse.cdt.gdb.ui",1289576715325 +stopped,bundle,org.eclipse.cdt.dsf.gdb,3.0.0.201009141542,"org.eclipse.cdt.dsf.gdb",1289576715325 +stopped,bundle,org.eclipse.cdt.launch,6.1.0.201009141542,"org.eclipse.cdt.launch",1289576715325 +stopped,bundle,org.eclipse.cdt.debug.ui,7.0.0.201009141542,"org.eclipse.cdt.debug.ui",1289576715326 +stopped,bundle,org.eclipse.cdt.debug.ui.memory.traditional,1.2.0.201009141542,"org.eclipse.cdt.debug.ui.memory.traditional",1289576715326 +stopped,bundle,org.eclipse.cdt.dsf,2.1.0.201009141542,"org.eclipse.cdt.dsf",1289576715326 +stopped,bundle,org.eclipse.cdt.debug.core,7.0.0.201009141542,"org.eclipse.cdt.debug.core",1289576715326 +stopped,bundle,org.eclipse.cdt.managedbuilder.ui,7.0.0.201009141542,"org.eclipse.cdt.managedbuilder.ui",1289576715331 +stopped,bundle,org.eclipse.cdt.make.ui,7.0.0.201009141542,"org.eclipse.cdt.make.ui",1289576715332 +stopped,bundle,org.eclipse.cdt.managedbuilder.gnu.ui,7.0.0.201009141542,"org.eclipse.cdt.managedbuilder.gnu.ui",1289576715332 +stopped,bundle,org.eclipse.cdt.managedbuilder.core,7.0.1.201009141542,"org.eclipse.cdt.managedbuilder.core",1289576715337 +stopped,bundle,org.eclipse.cdt.make.core,7.0.0.201009141542,"org.eclipse.cdt.make.core",1289576715337 +stopped,bundle,org.eclipse.cdt.mylyn.ui,1.1.3.v20100909-0100-e3x,"org.eclipse.cdt.mylyn.ui",1289576715338 +stopped,bundle,org.eclipse.cdt.ui,5.2.1.201009141542,"org.eclipse.cdt.ui",1289576715338 +stopped,bundle,org.eclipse.cdt.core,5.2.1.201009141542,"org.eclipse.cdt.core",1289576715360 +stopped,bundle,org.eclipse.equinox.p2.ui.sdk,1.0.100.v20100513,"org.eclipse.equinox.p2.ui.sdk",1289576715360 +stopped,bundle,org.eclipse.search,3.6.0.v20100520-0800,"org.eclipse.search",1289576715360 +stopped,bundle,org.eclipse.mylyn.team.ui,3.4.2.v20100909-0100-e3x,"org.eclipse.mylyn.team.ui",1289576715360 +stopped,bundle,org.eclipse.ui.navigator.resources,3.4.201.M20100707-0800,"org.eclipse.ui.navigator.resources",1289576715361 +stopped,bundle,org.eclipse.ltk.ui.refactoring,3.5.0.v20100526-0800,"org.eclipse.ltk.ui.refactoring",1289576715361 +stopped,bundle,org.eclipse.mylyn.bugzilla.ui,3.4.2.v20100909-0100-e3x,"org.eclipse.mylyn.bugzilla.ui",1289576715361 +stopped,bundle,org.eclipse.mylyn.ide.ui,3.4.0.v20100608-0100-e3x,"org.eclipse.mylyn.ide.ui",1289576715361 +stopped,bundle,org.eclipse.mylyn.resources.ui,3.4.1.v20100909-0100-e3x,"org.eclipse.mylyn.resources.ui",1289576715361 +stopped,bundle,org.eclipse.mylyn.wikitext.tasks.ui,1.3.1.v20100823-0100-e3x,"org.eclipse.mylyn.wikitext.tasks.ui",1289576715361 +stopped,bundle,org.eclipse.mylyn.context.ui,3.4.1.v20100909-0100-e3x,"org.eclipse.mylyn.context.ui",1289576715361 +stopped,bundle,org.eclipse.mylyn.help.ui,3.4.1.v20100823-0100-e3x,"org.eclipse.mylyn.help.ui",1289576715362 +stopped,bundle,org.eclipse.mylyn.tasks.bugs,3.4.1.v20100823-0100-e3x,"org.eclipse.mylyn.tasks.bugs",1289576715362 +stopped,bundle,org.eclipse.mylyn.tasks.ui,3.4.2.v20100902-0100-e3x,"org.eclipse.mylyn.tasks.ui",1289576715362 +stopped,bundle,org.eclipse.team.cvs.ui,3.3.301.R36x_v20100825-0800,"org.eclipse.team.cvs.ui",1289576715375 +stopped,bundle,org.eclipse.team.ui,3.5.101.R36x_v20100825-0800,"org.eclipse.team.ui",1289576715379 +stopped,bundle,org.eclipse.compare,3.5.100.I20100526-0800,"org.eclipse.compare",1289576715380 +stopped,bundle,org.eclipse.cdt.debug.ui.memory.transport,2.1.0.201009141542,"org.eclipse.cdt.debug.ui.memory.transport",1289576715381 +stopped,bundle,org.eclipse.ui.externaltools,3.2.0.v20100427,"org.eclipse.ui.externaltools",1289576715381 +stopped,bundle,org.eclipse.debug.ui,3.6.1.v20100901_r361,"org.eclipse.debug.ui",1289576715381 +stopped,bundle,org.eclipse.mylyn.wikitext.ui,1.3.0.v20100608-0100-e3x,"org.eclipse.mylyn.wikitext.ui",1289576715381 +stopped,bundle,org.eclipse.ui.console,3.5.0.v20100526,"org.eclipse.ui.console",1289576715381 +stopped,bundle,org.eclipse.mylyn.commons.ui,3.4.0.v20100608-0100-e3x,"org.eclipse.mylyn.commons.ui",1289576715381 +stopped,bundle,org.eclipse.ui.editors,3.6.1.r361_v20100825-0800,"org.eclipse.ui.editors",1289576715381 +stopped,bundle,org.eclipse.ui.workbench.texteditor,3.6.1.r361_v20100714-0800,"org.eclipse.ui.workbench.texteditor",1289576715381 +stopped,bundle,org.eclipse.compare.core,3.5.100.I20100526-0800,"org.eclipse.compare.core",1289576715383 +stopped,bundle,org.eclipse.epp.mpc.ui,1.0.1.v20100826-2143,"org.eclipse.epp.mpc.ui",1289576715383 +stopped,bundle,org.eclipse.epp.usagedata.ui,1.3.0.R201005261100,"org.eclipse.epp.usagedata.ui",1289576715383 diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml new file mode 100644 index 0000000..95ca575 --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.ide/dialog_settings.xml @@ -0,0 +1,5 @@ + +
+
+
+
diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml new file mode 100644 index 0000000..9c43768 --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -0,0 +1,7 @@ + +
+
+
+
+
+
diff --git a/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml new file mode 100644 index 0000000..2d128fb --- /dev/null +++ b/Master/Real-Time Systems/mki/.metadata/.plugins/org.eclipse.ui.workbench/workbench.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Master/Real-Time Systems/mki/.project b/Master/Real-Time Systems/mki/.project new file mode 100644 index 0000000..7572153 --- /dev/null +++ b/Master/Real-Time Systems/mki/.project @@ -0,0 +1,78 @@ + + + mki + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.autoBuildTarget + all + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.cleanBuildTarget + clean + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.fullBuildTarget + all + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/Master/Real-Time Systems/mki/Makefile b/Master/Real-Time Systems/mki/Makefile new file mode 100644 index 0000000..3acaba0 --- /dev/null +++ b/Master/Real-Time Systems/mki/Makefile @@ -0,0 +1,10 @@ + +all: + g++ -O2 -g -c -Wall ./src/mki.cpp + g++ -O2 -g -c -Wall ./src/libcanio.cpp + g++ -O2 -g -c -Wall ./test/mkidemo.cpp + g++ -o ./mkidemo mki.o libcanio.o mkidemo.o + ar cq libcanio.a libcanio.o + +clean: + rm -f mki.* mkidemo* libcanio.* diff --git a/Master/Real-Time Systems/mki/src/libcanio.cpp b/Master/Real-Time Systems/mki/src/libcanio.cpp new file mode 100644 index 0000000..52cf12c --- /dev/null +++ b/Master/Real-Time Systems/mki/src/libcanio.cpp @@ -0,0 +1,680 @@ +//============================================================================ +// Name: +// libcanio.cpp +// +// Summary: +// A pretty simple library for the SocketCan layer, which trys to make +// the communication with the interfaces a bit easier, thus saving the +// tedious research time needed to get things up and running. +// +// Created on: +// Sep 24, 2010 +// +// Author: +// Christian Steiger +//============================================================================ + +// TODO CanIO interface - Read me first! +// As you can see there are a lot of "placeholder routine" TODOs in this file, +// normally filters can be set per setsocketopt, but not during runtime. +// Well, it was mentioned on the following page that this is possible... +// http://www.brownhat.org/docs/socketcan/llcf-api.html +// ...but i wasnt yet able to find the one command to do it, +// and my time for this project is rapidly running out. So the current +// filter implementation is a crude one in software that needs to be +// replaced with the real thing. Comments and function types already 'fit' +// more or less, so changes on the class interface shouldnt be neccesary. + +// Includes +#include "libcanio.h" + +// Constructor +CanIO::CanIO() +{ + // set default variables + m_socket = 0; + m_print_errors = 1; + m_filter = 0; + m_filter_size = 0; + m_filter_active = 0; +} + +// Destructor +CanIO::~CanIO() +{ + // properly close the socket + disconnect(); +} + +//============================================================================ +// Summary: +// Connects to an socket can interface +// Parameters: +// [in] interface - name of the can interface, e.g. can0, vcan0 +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::connect(const char* const interface) +{ + // disconnect if theres already an socket present + if (m_socket) + disconnect(); + + // create needed variables + struct sockaddr_can addr; + struct ifreq ifr; + int ret; + + // create a socket handler + m_socket = socket(PF_CAN, SOCK_RAW, CAN_RAW); + + // invalid socket_handler? + if (m_socket < 0) + { + // print error message if wanted + if (m_print_errors) + perror("CanIO::connect, socket"); + + // return the result + return m_socket; + } + + // copy the name of the wanted interface into the ifreq struct + strcpy(ifr.ifr_name, interface); + + // and get the interface index via ioctl for further operations + ret = ioctl(m_socket, SIOCGIFINDEX, &ifr); + + // check for errors + if (ret < 0) + { + // prints errno message if wanted + if (m_print_errors) + perror("CanIO::connect, ioctl"); + + // close socket + disconnect(); + + // return the result + return ret; + } + + if (m_filter_active) + setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_FILTER, + m_filter, + m_filter_size * sizeof(can_filter) + ); + + // copy the info we got from the ioctl call + addr.can_ifindex = ifr.ifr_ifindex; + + // set the protocol/implementation we want to use + addr.can_family = AF_CAN; + + // bind the socket to the device + ret = bind(m_socket, (struct sockaddr *)&addr, sizeof(addr)); + + // check for errors and prints errno message if wanted + if (ret < 0) + { + // print errormessage if wanted + if (m_print_errors) + perror("CanIO::connect, bind"); + + // close socket + disconnect(); + } + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// Disconnects from a socket can interface +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::disconnect(void) +{ + // just abort if there isnt a socket + if (!m_socket) + return 0; + + // close socket connection + int ret = close(m_socket); + + // set m_socket to 0 + m_socket = 0; + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::disconnect, close"); + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// Reads a can message from the device. The read ist blocking, +// if there arent new messages it will wait until one is available! +// Parameters: +// [in] frame - pointer to a can_frame where the message data is stored. +// take a look in /usr/include/linux/can.h for more details. +// The message type is also in the can_id field, use the masks +// CAN_EFF_FLAG, CAN_RTR_FLAG and CAN_ERR_FLAG to determine it. +// [in] timestamp - a pointer to a timeval struct, contains sec and usec. +// [out] 0 on success, -1 on failure (sets errno), -2 on incomplete frames. +//============================================================================ +ssize_t CanIO::readMsg(can_frame* frame, timeval* timestamp) +{ + // detect nullpointer + if (!frame) + { + // set errno, invalid argument + errno = EINVAL; + + // print error message if wanted + if (m_print_errors) + perror("CanIO::readMsg"); + + // return the failure + return -1; + } + + // create temporary variables + ssize_t nbytes; + + // look at the placeholder comment below + readmsg_loop: + + // read a can message from the bus + nbytes = read(m_socket, frame, sizeof(can_frame)); + + // check for errors + if (nbytes < 0) + { + // print errno message if wanted + if (m_print_errors) + perror("CanIO::readMsg, read"); + + // return the result + return nbytes; + } + + // check for a complete frame + // note: we cant fetch missing bytes, each read, even with a byte length of 1, + // will get the starting bytes of a new message instead of the missing ones. + if (nbytes < (signed int)sizeof(can_frame)) + { + // print error message if wanted + if (m_print_errors) + fprintf(stderr, "CanIO::readMsg, read: incomplete CAN frame.\n"); + + // returns -2 for error indication + return -2; + } + + // check if a timestamp is wanted + if ( timestamp ) + { + // misuse the nbyte variable to get ioctls result + nbytes = ioctl(m_socket, SIOCGSTAMP, timestamp); + + // was there an error? + if (nbytes < 0) + { + // print error if wanted + if (m_print_errors) + perror("CanIO::readMsg, ioctl"); + + // returns the result + return nbytes; + } + } + + // TODO CanIO::ReadMsg - Placeholder, remove this part when you rewrite the filter functions. + // Its a simple goto command, ugly, but saves code. Dont forget to remove the mark above too. + if (m_filter_active > 0) + while(!isVisible(frame->can_id)) + goto readmsg_loop; + + // everything ok, return 0 + return 0; +} + + +//============================================================================ +// Summary: +// Trys to write a can message to the device. +// Parameters: +// [in] frame - pointer to a can_frame struct which contains the message_data. +// [in] frame - pointer to a can_frame struct where the message data is stored. +// take a look in /usr/include/linux/can.h for more details. +// The message type is also in the can_id field, use the flags +// CAN_EFF_FLAG, CAN_RTR_FLAG and CAN_ERR_FLAG to set it. +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +ssize_t CanIO::writeMsg(const can_frame* const frame) +{ + // detect nullpointer + if (!frame) + { + // set errno, invalid argument + errno = EINVAL; + + // print error message if wanted + if (m_print_errors) + perror("CanIO::writeMsg"); + + // return the failure + return -1; + } + + // try to write to the device and return the result + int ret = write(m_socket, frame, sizeof(struct can_frame)); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::writeMsg, write"); + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// Dont print error messages on stderr. +// Useful if you do want to to the errorhandling yourself. +// Parameters: +// none +//============================================================================ +void CanIO::hideErrors(void) +{ + m_print_errors = 0; +} + +//============================================================================ +// Summary: +// Print error messages on stderr. +// Useful for debugging purposes, enabled per default. +// Parameters: +// none +//============================================================================ +void CanIO::showErrors(void) +{ + m_print_errors = 1; +} + + +//============================================================================ +// Summary: +// The driver is able to generate error frames which can be passed to the +// application in the same way like other can messages, +// This command enables this feature. +// Parameters: +// [in] mask - The errors are divided in different error classes which +// can be filtered with the appropiate masks. +// To get every error just ignore this argument, otherwise +// set the masks for the errors you would like to see. +// Take a look at /usr/include/linux/can/error.h for masks. +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::showCanErrors(const can_err_mask_t err_mask) +{ + // create temporary variables + can_err_mask_t mask = err_mask; + + // check the mask value + if (!mask) + mask = CAN_ERR_MASK; + + // return the results of setsockopt + int ret = setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_ERR_FILTER, + &mask, + sizeof(mask) + ); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::showCanErrors, setsockopt"); + + // return the result + return ret; + +} + +//============================================================================ +// Summary: +// The driver can generate error frames which can be passed to the +// application in the same way like other can messages, +// this command disables this feature (default). +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::hideCanErrors(void) +{ + // set the mask to zero + can_err_mask_t mask = 0; + + // return the results of setsockopt + int ret = setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_ERR_FILTER, + &mask, + sizeof(mask) + ); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::hideCanErrors, setsockopt"); + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// TODO CanIO::enableLoopBack() - Describe me! +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::enableLoopBack(void) +{ + // create temporary variables + const int loopback = 1; + int ret; + + // set the loopback state + ret = setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_LOOPBACK, + &loopback, + sizeof(loopback) + ); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::enableLoopBack, setsockopt"); + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// TODO CanIO::disableLoopBack() - Describe me! +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::disableLoopBack(void) +{ + // create temporary variables + const int loopback = 0; + int ret; + + // set the loopback state + ret = setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_LOOPBACK, + &loopback, + sizeof(loopback) + ); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::disableLoopBack, setsockopt"); + + // return the result + return ret; +} + + +//============================================================================ +// Summary: +// TODO CanIO::enableRecvOwnMsgs() - Describe me! +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::enableRecvOwnMsgs(void) +{ + // create temporary variables + const int recv_own_msgs = 1; + int ret; + + // set the loopback state + ret = setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_RECV_OWN_MSGS, + &recv_own_msgs, + sizeof(recv_own_msgs) + ); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::enableRecvOwnMsgs, setsockopt"); + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// TODO CanIO::disableRecvOwnMsgs() - Describe me! +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int CanIO::disableRecvOwnMsgs(void) +{ + // create temporary variables + const int recv_own_msgs = 0; + int ret; + + // set the loopback state + ret = setsockopt( + m_socket, + SOL_CAN_RAW, + CAN_RAW_RECV_OWN_MSGS, + &recv_own_msgs, + sizeof(recv_own_msgs) + ); + + // check for errors and prints errno message if wanted + if (ret < 0 && m_print_errors) + perror("CanIO::disableRecvOwnMsgs, setsockopt"); + + // return the result + return ret; +} + +//============================================================================ +// Summary: +// Adds a custom can id filter +// Parameters: +// [in] rfilter - Points to an can_filter struct which contains the filter. +// [in] size - The size of the rfilter. +// [out] 0 on success, -1 on failure, sets errno. +// +// Filter example: +// This shows messages with an id between 0x200 and 0x2FF: +// rfilter.can_id = 0x200; +// rfilter.can_mask = 0xF00; +// +// While this hides messages with in id between 0x200 and 0x2FF: +// rfilter.can_id = 0x200 | CAN_INV_FILTER; +// rfilter.can_mask = 0xF00; +// +// More filters can be combined like this: +// rfilter[0].can_id = 0x00001234; // exactly this EFF frame +// rfilter[0].can_mask = CAN_EFF_MASK; +// rfilter[1].can_id = 0x234; // exactly this SFF frame +// rfilter[1].can_mask = CAN_SFF_MASK; +//============================================================================ +// TODO CanIO::addFilter() - Placeholder routine, rewrite for setsockopt. +int CanIO::addFilter(const can_filter* const filter, const unsigned int size) +{ + // detect nullpointer and wrong size + if (!filter || size < sizeof(can_filter)) + { + // set errno, invalid argument + errno = EINVAL; + + // print error message if wanted + if (m_print_errors) + perror("CanIO::addFilter"); + + // return the failure + return -1; + } + + // calculate the arraysize + unsigned int arraysize = (size / sizeof(can_filter)); + + // if there arnt already rules defined + if (!m_filter) + { + // create a new array of pointers to can_filter + m_filter = new can_filter[arraysize]; + + // just copy the data + memcpy(m_filter, filter, size); + + // set the new arraysize + m_filter_size = arraysize; + } + + // if there are already rules, extend the set + else + { + // copy the pointer from the old array + can_filter *temp = m_filter; + + // create a new one, with the size of the two rulesets + m_filter = new can_filter[ arraysize + m_filter_size ]; + + // copy the old one + memcpy(m_filter, temp, m_filter_size * sizeof(can_filter)); + + // copy the new one after the end of the old one + memcpy(m_filter + m_filter_size, filter, size); + + // set the new filter size + m_filter_size += arraysize; + + // delete the content of the old pointer + delete temp; + } + + // enable the filter + if (!m_filter_active) + m_filter_active = 1; + + // everything okay + return 0; +} + +//============================================================================ +// Summary: +// Enables the filter, put already stored filter rules back to work. +// addFilter does this automatically, use disableFilter to prevent it. +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +// TODO CanIO:enableFilter() - Placeholder routine, rewrite for setsockopt. +int CanIO::enableFilter(void) +{ + // sets filter activity + m_filter_active = 1; + + // placeholder for setsockopt returns + return 0; +} + +//============================================================================ +// Summary: +// Disables the Filter, but keep the filter rules in the background. +// Stays disabled until you call enableFilter, regardless of addFilter calls. +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +// TODO CanIO:disableFilter() - Placeholder routine, rewrite for setsockopt. +int CanIO::disableFilter(void) +{ + // sets filter activity + m_filter_active = -1; + + // placeholder for setsockopt returns + return 0; +} + +//============================================================================ +// Summary: +// Simply resets the filter. +// Parameters: +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +// TODO CanIO::clearFilter() - Placeholder routine, rewrite for setsockopt. +int CanIO::clearFilter(void) +{ + // reset filter size + m_filter_size = 0; + + // delete only when there is a pointer + if (m_filter) + delete m_filter; + + // Everything okay + return 0; +} + +//============================================================================ +// Summary: +// Checks if the given can id is visible or not. +// Dont use this function, it will be obsolete when +// the filter functions get a better implementation +// Parameters: +// [in] id - The can id +// [out] True or false, depending on visibility +//============================================================================ +// TODO CanIO::isVisible() - Placeholder help routine, remove it when you rewrite the filter functions. +char CanIO::isVisible(const unsigned int id) +{ + // declare variables + short unsigned int i; + char visible = 0; + + // go through the filter rules + for (i = 0; i < m_filter_size; i++) + { + // make things much easier to read, + // gcc -O2 will take hopefully care of it + const unsigned int rule = (m_filter + i)->can_mask & (m_filter + i)->can_id; + const unsigned int input = (m_filter + i)->can_mask & id; + + // inverted filter? + if ((m_filter + i)->can_id & CAN_INV_FILTER) + { + if (rule != input) + return 1; + } + else + { + if (rule == input) + return 1; + } + } + // Everything okay + return visible; +} + + diff --git a/Master/Real-Time Systems/mki/src/libcanio.h b/Master/Real-Time Systems/mki/src/libcanio.h new file mode 100644 index 0000000..8f57b14 --- /dev/null +++ b/Master/Real-Time Systems/mki/src/libcanio.h @@ -0,0 +1,81 @@ +//============================================================================ +// Name: +// libcanio.h +// +// Summary: +// A pretty simple interface to the SocketCan layer, +// which trys to make the communication with the can interfaces easier. +// +// Created on: +// Sep 24, 2010 +// +// Author: +// Christian Steiger +//============================================================================ + +#ifndef LIBCANIO_H_ +#define LIBCANIO_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +class CanIO +{ + public: + // constructor and destructor + CanIO(); + virtual ~CanIO(); + + // connect and disconnect + int connect(const char* const interface = "can0"); + int disconnect(void); + + // read and write messages + ssize_t readMsg(can_frame* frame, timeval* timestamp = 0); + ssize_t writeMsg(const can_frame* const frame); + + // socketcan options + int showCanErrors(const can_err_mask_t err_mask = 0); + int hideCanErrors(void); + int enableLoopBack(void); + int disableLoopBack(void); + int enableRecvOwnMsgs(void); + int disableRecvOwnMsgs(void); + + // filter functions + int addFilter(const can_filter* const filter, const unsigned int size); + int enableFilter(void); + int disableFilter(void); + int clearFilter(void); + + // debugging help + void hideErrors(void); + void showErrors(void); + + protected: + // class members + int m_socket; + char m_print_errors; + char m_filter_active; + can_filter* m_filter; + unsigned short int m_filter_size; + + private: + // dont use this function, it will be obsolete when + // the filter functions get a better implementation + char isVisible(const unsigned int id); + +}; + +#endif diff --git a/Master/Real-Time Systems/mki/src/mki.cpp b/Master/Real-Time Systems/mki/src/mki.cpp new file mode 100644 index 0000000..1438679 --- /dev/null +++ b/Master/Real-Time Systems/mki/src/mki.cpp @@ -0,0 +1,439 @@ +//============================================================================ +// Name: +// mki.cpp +// +// Summary: +// A pretty simple class for controlling the parts +// we can on the mercedes-combi-instrument +// +// Created on: +// Okt 1, 2010 +// +// Author: +// Christian Steiger +//============================================================================ + +#include "mki.h" + +// constructor +mki::mki() +{ + // set data + m_alert = 0; + + // clean up structs + memset(&m_can_id_200, 0, sizeof(m_can_id_200)); + memset(&m_can_id_208, 0, sizeof(m_can_id_208)); + memset(&m_can_id_210, 0, sizeof(m_can_id_210)); + memset(&m_can_id_308, 0, sizeof(m_can_id_308)); + memset(&m_can_id_312, 0, sizeof(m_can_id_312)); + memset(&m_can_id_550, 0, sizeof(m_can_id_550)); + memset(&m_can_id_608, 0, sizeof(m_can_id_608)); + + // set message ids + m_can_id_200.can_id = 0x200; + m_can_id_208.can_id = 0x208; + m_can_id_210.can_id = 0x210; + m_can_id_308.can_id = 0x308; + m_can_id_312.can_id = 0x312; + m_can_id_550.can_id = 0x550; + m_can_id_608.can_id = 0x608; + + // set message length + m_can_id_200.can_dlc = 8; + m_can_id_208.can_dlc = 8; + m_can_id_210.can_dlc = 8; + m_can_id_308.can_dlc = 8; + m_can_id_312.can_dlc = 8; + m_can_id_550.can_dlc = 8; + m_can_id_608.can_dlc = 8; +} + +// destructor +mki::~mki() +{ + +} + + +//============================================================================ +// Summary: +// Connects to an socket can interface. +// Parameters: +// [in] interface - name of the can interface, e.g. can0, vcan0 +// [out] 0 on success, -1 on failure, sets errno. +//============================================================================ +int mki::connect( const char* const interface ) +{ + return m_can.connect( interface ); + +} + +//============================================================================ +// Summary: +// Enables some of the available lamps in the cockpit. +// +// Possible values are: +// MKI_ABS, MKI_ESP, MKI_ENGINE, MKI_WARN, +// MKI_WARN_BLINK, MKI_FUEL_LOW +// MKI_HANDBRAKE will cause alarm beep when Mph > 0 +// +// Combine them via logical OR to enable more than one at the same time. +// Each call will reset the lamp status, so a setLamps(0) will disable all. +// +// Parameters: +// [in] lamps - bitmask which contains the lamps to activate. +//============================================================================ +void mki::setLamps( const unsigned int lamps ) +{ + // erase the used bytes to make things easier + m_can_id_200.data[0] = 0; + m_can_id_308.data[3] = 0; + + // activate handbrake lamp. can cause alarm beep when moving + if ( lamps & MKI_HANDBRAKE ) + m_can_id_200.data[0] |= 0x02; + + // activate abs lamp + if ( lamps & MKI_ABS ) + m_can_id_200.data[0] |= 0x04; + + // activate esp lamp + if ( lamps & MKI_ESP ) + m_can_id_200.data[0] |= 0x08; + + // activate warning triangle + if ( lamps & MKI_WARN ) + m_can_id_200.data[0] |= 0x10; + + // activate warning triangle and let it blink. ignores MKI_WARN. + if ( lamps & MKI_WARN_BLINK ) + m_can_id_200.data[0] |= 0x20; + + // activate fuel low lamp + if ( lamps & MKI_FUEL_LOW ) + m_can_id_308.data[3] |= 0x01; + + // activate engine lamp + if ( lamps & MKI_ENGINE ) + m_can_id_308.data[3] |= 0x02; + +} + +void mki::setLampsOff( void ) +{ + // erase the used bytes to make things easier + m_can_id_200.data[0] = 0; + m_can_id_308.data[3] = 0; + + // activate handbrake lamp. can cause alarm beep when moving + + m_can_id_200.data[0] |= 0x00; + + +} + + + + + +//============================================================================ +// Summary: +// Sets the Rpm. +// Parameters: +// [in] rpm - the rpm to be set, only values between 0 and 7000 make sense. +//============================================================================ +void mki::setRpm( const unsigned short rpm ) +{ + // dont allow values higher than 7000, or you may not see anyhting + const unsigned short int rpm_ = (rpm > 7000) ? 7000 : rpm; + + // convert the rpm for the message bytes + const unsigned short int hbyte = rpm_ / 250; + const unsigned short int lbyte = rpm_ - (hbyte * 250); + + // set variables + m_can_id_308.data[1] = hbyte; + m_can_id_308.data[2] = lbyte; +} + + +//============================================================================ +// Summary: +// Sets the Mph. +// Parameters: +// [in] mph - the mph to be set, only values between 0 and 160 make sense. +//============================================================================ +void mki::setMph( const unsigned char mph ) +{ + // calculate low and high byte + unsigned short int hbyte = mph / 10; + unsigned short int lbyte = (mph - (hbyte * 10)) * 25; + + // filter high byte, since bit 6 and 7 make the hbyte value invalid + hbyte &= 0x3F; + + // set address 0x200 properties + m_can_id_200.data[2] = hbyte; + m_can_id_200.data[3] = lbyte; + m_can_id_200.data[4] = hbyte; + m_can_id_200.data[5] = lbyte; + + // set address 0x208 properties + m_can_id_208.data[4] = hbyte; + m_can_id_208.data[5] = lbyte; + m_can_id_208.data[6] = hbyte; + m_can_id_208.data[7] = lbyte; + +} + + +//============================================================================ +// Summary: +// Sets the cooling water temperature. +// Just give the value you want to see in degree, e.g. setCWTemp(85). +// Only values between 40 and 130 make sense, everything else +// wont be displayed due to display limitatios. +// +// Parameters: +// [in] temp - the temperature to be set. +//============================================================================ +void mki::setCWTemp( const unsigned char temp ) +{ + // we need to add an offset of 40 to show the temperature 1:1, + // since the display wont show anything when we reach 0xFF, + // we will simply limit the value to the highest possible setting. + m_can_id_608.data[0] = ((temp + 40) > 176) ? 176 : temp + 40; +} + + +//============================================================================ +// Summary: +// Sets the properties of the limit mode which is shown in the lcd-display. +// +// Possible values are: +// MKI_LIMIT = activates a big limit view in the lcd-display, +// if no changes are made it will switch back and forth +// between the main and limit display for a short while, +// and then stays in the main mode. +// MKI_LIMIT_TEXT = activates a small limit text in the main display mode. +// MKI_PERMANENT = make the MKI_LIMIT view permanently visible. +// MKI_EXCEED = alarm beep and "exceeded" message in the limit view. +// MKI_WINTER_TYRE = switches "limit" text to "winter tyre limit". +// MKI_MPH_BLINK = let the mph value blink. +// MKI_NO_MPH = show --- instad of the mph value. +// +// The mph value shown there can be controlled with setLimitMph(mph); +// +// Parameters: +// [in] flags - a bitmask which control the different modes. +//============================================================================ +void mki::setDisplay( const unsigned int flags ) +{ + + // just kill the data content except for byte 7 + // makes life much easier for us in this function + unsigned short int i; + for (i = 0; i < 7; i++) + m_can_id_210.data[i] = 0; + + // enable limit display + if ( flags & MKI_LIMIT ) + m_can_id_210.data[5] |= 0x01; + + // set permanent limit display + if ( flags & MKI_PERMANENT ) + m_can_id_210.data[3] = 0x80; + + // shall the mph value blink? + if ( flags & MKI_MPH_BLINK ) + m_can_id_210.data[5] |= 0x02; + + // --- instead of mph value? + if ( flags & MKI_NO_MPH ) + m_can_id_210.data[5] |= 0x08; + + // enable winter tyre message instad of limit + if ( flags & MKI_NO_MPH ) + m_can_id_210.data[5] |= 0x08; + + // exceed warning with alarm sound + if ( flags & MKI_EXCEED ) + m_can_id_210.data[4] |= 0x01; + + // exceed warning with alarm sound + if ( flags & MKI_LIMIT_TEXT ) + m_can_id_210.data[4] |= 0x08; + +} + + +//============================================================================ +// Summary: +// Sets the Mph you see in the limit display if you activate +// it via setDisplay(MKI_LIMIT) or setDisplay(MKI_LIMIT_TEXT). +// Parameters: +// [in] mph - the mph to be set, a value between 0 and 255. +//============================================================================ +void mki::setDisplayMph( const unsigned char mph ) +{ + // just copy the value + m_can_id_210.data[7] = mph; + +} + + +//============================================================================ +// Summary: +// Sets an alert message. Possible alerts are: +// +// MKI_OIL_LOW = shows "engine oil level, stop. ENGINE OFF!" alert. +// MKI_TIRE_PRESSURE = shows "tire pressure low, check tires". +// MKI_TIRE_DEFECT = shows "tire pressure low, caution tire defect!". +// +// The alerts can be combined via logical OR, in this case it will +// alert beep once for every error and then switch back and forth +// between the enabled alerts, MKI_TIRE_DEFECT however overrides +// MKI_TIRE_PRESSURE, so you wont see it after setting MKI_TIRE_DEFECT. +// +// To deactivate the alerts just call setAlert(0). +// It can also take a second or two until the alert gets active. +// +// Parameters: +// [in] alert - see the description above. +//============================================================================ +void mki::setAlert( const unsigned int alert ) +{ + // we have a alert + if (alert) + { + // set the appropiate variable so + // sendData() will send the 0x550 message + m_alert = 1; + + // kill byte to make things easier + m_can_id_550.data[0] = 0; + + // tire pressure low alert + if ( alert & MKI_TIRE_PRESSURE ) + m_can_id_550.data[0] |= 0x10; + + // tire defect alert + if ( alert & MKI_TIRE_DEFECT ) + m_can_id_550.data[0] |= 0x20; + + } + else + { + // unset the appropiate variable so + // sendData() wont send the 0x550 message + m_alert = 0; + } +} + + +//============================================================================ +// Summary: +// Sends all the messages the display needs to function. +// You need to call this command every 50ms or so to keep +// everything working, best use a while-loop like this: +// +// while (1) { mki_object.sendData(); usleep(50000); } +// +// It may be tedious, but makes usage a bit easier, and you can decide +// on your own how to implement it (let it run in a seperate pthread or so). +// +// Be aware that the function itself sleeps a good time to prevent +// write buffer overflows, together its roughly 50ms, +// 60ms if you enabled alerts. +// +// Parameters: +// none +//============================================================================ +// TODO mki::sendData() - Implement error handling to make it more solid. +void mki::sendData(void) +{ + + // sleep 10ms between the messages to prevent + // write buffer error that will happen otherwise. + m_can.writeMsg(&m_can_id_200); + usleep(1000); + + m_can.writeMsg(&m_can_id_208); + usleep(1000); + + m_can.writeMsg(&m_can_id_210); + usleep(1000); + + m_can.writeMsg(&m_can_id_308); + usleep(1000); + + m_can.writeMsg(&m_can_id_312); + usleep(1000); + + m_can.writeMsg(&m_can_id_608); + usleep(1000); + + // Only write 550 if we have alerts + if (m_alert) { + m_can.writeMsg(&m_can_id_550); + usleep(1000); + } + +} + +//============================================================================ +// Summary: +// Sets the Kmh. +// Works the same wike like setMph(), the Kmh will be converted +// into Mph and then shown on the display. +// +// Parameters: +// [in] mph - the mph to be set, only values between 0 and 255 make sense. +//============================================================================ +void mki::setKmh ( const unsigned char kmh ) +{ + // convert bewteen kmh and mph + // and call the appropiate function + setMph( (char)(kmh * 0.6f) ); +} + + +//============================================================================ +// Summary: +// Sets the Kmh for the limit modes. +// Works the same wike like setDisplayMph(), the Kmh will be converted +// into Mph and then shown on the display if you used +// setDisplay(MKI_LIMIT) or setDisplay(MKI_LIMIT_TEXT). +// +// Parameters: +// [in] mph - the mph to be set, only values between 0 and 255 make sense. +//============================================================================ +void mki::setDisplayKmh ( const unsigned char kmh ) +{ + // convert bewteen kmh and mph + // and call the appropiate function + setMph( (char)(kmh * 0.6f) ); +} + + +//============================================================================ +// Summary: +// Gives back a pointer to the CanIO class that is used to connect +// to the can interface. Allows you to set some properties like +// hideErrors() or Loopback. Be cautious with it, the mki-class isnt +// really prepared for some of the errors you could cause with it. +// +// Parameters: +// [out] mph - the mph to be set, only values between 0 and 255 make sense. +//============================================================================ +// TODO mki::getInterface - Try to optimize the class in a way that allows us to remove this function. +// At the moment the error handling is pretty bad, so you will get spammed with error messages or +// gibberisch when you try to send and the interface isnt up for example, so this needs work. +CanIO* mki::getInterface(void) +{ + // return the reference + return &m_can; +} + + diff --git a/Master/Real-Time Systems/mki/src/mki.h b/Master/Real-Time Systems/mki/src/mki.h new file mode 100644 index 0000000..f2ef77b --- /dev/null +++ b/Master/Real-Time Systems/mki/src/mki.h @@ -0,0 +1,86 @@ +//============================================================================ +// Name: +// mki.h +// +// Summary: +// A pretty simple class for controlling the parts +// we can on the mercedes-combi-instrument +// +// Created on: +// Okt 1, 2010 +// +// Author: +// Christian Steiger +//============================================================================ + +// includes +#include "libcanio.h" + +// defines to make things easier, take a look at mkp.cpp +// to see what they are doing exactly. + +// lamps on the display (mki::setLamps()) +#define NONE 0x00 +#define MKI_ABS 0x01 +#define MKI_ESP 0x02 +#define MKI_HANDBRAKE 0x04 +#define MKI_ENGINE 0x08 +#define MKI_WARN 0x10 +#define MKI_WARN_BLINK 0x20 +#define MKI_FUEL_LOW 0x40 + +// lcd display options (mki::setDisplay()) +#define MKI_LIMIT 0x01 +#define MKI_LIMIT_TEXT 0x02 +#define MKI_PERMANENT 0x04 +#define MKI_EXCEED 0x08 +#define MKI_WINTER_TYRE 0x10 +#define MKI_MPH_BLINK 0x10 +#define MKI_NO_MPH 0x20 + +// warnings (mki::setAlert()) +#define MKI_OIL_LOW 0x01 +#define MKI_TIRE_PRESSURE 0x02 +#define MKI_TIRE_DEFECT 0x04 + + +// class definition +class mki +{ + public: + // constructor and destructor + mki(); + ~mki(); + + // various methods, see mki.cpp for descriptions + int connect( const char* const interface ); + void setLamps( const unsigned int lamps); + void setLampsOff(void); + void setRpm( const unsigned short rpm ); + void setMph( const unsigned char mph ); + void setCWTemp( const unsigned char temp ); + void setDisplayMph( const unsigned char mph ); + void setDisplay( const unsigned int flags ); + void setAlert( const unsigned int problem ); + + void sendData(void); + + void setKmh ( const unsigned char kmh ); + void setDisplayKmh ( const unsigned char kmh ); + + // dont rely to heavily on this, it should be removed asap. + CanIO* getInterface(void); + + protected: + // class members + CanIO m_can; + unsigned char m_alert; + + can_frame m_can_id_200; + can_frame m_can_id_208; + can_frame m_can_id_210; + can_frame m_can_id_308; + can_frame m_can_id_312; + can_frame m_can_id_550; + can_frame m_can_id_608; +}; diff --git a/Master/Real-Time Systems/mki/test/mkidemo.cpp b/Master/Real-Time Systems/mki/test/mkidemo.cpp new file mode 100644 index 0000000..e5f8729 --- /dev/null +++ b/Master/Real-Time Systems/mki/test/mkidemo.cpp @@ -0,0 +1,130 @@ +//============================================================================ +// Name: +// mkidemo.cpp +// +// Summary: +// Extremly simple demo program that shows some values +// on the mercedes combi instrument. needs libcanio to work. +// +// Default interface is can0, to change it start the program like this: +// mkidemo -f=can1 +// +// Created on: +// Okt 1, 2010 +// +// Author: +// Christian Steiger +//============================================================================ + + +// includes +#include "../src/mki.h" + +// Function prototypes +const char* const fetchinterface (const int argc, const char* const argv[]); + +// Main function +int main(int argc, char *argv[]) +{ + int mph =0; + int temperatur=40; + int rpm =0; + // get the interface data from the command line + const char* const interface = fetchinterface(argc, argv); + + // create mki object + mki m; + + // connect to interface, stop if we cant connect + if (m.connect(interface) < 0) + return -1; + + //m.getInterface()->disableLoopBack(); + + // set informations we want to display + //m.setLamps(MKI_WARN | MKI_FUEL_LOW | MKI_WARN_BLINK | MKI_ABS); + + //m.setDisplay(MKI_LIMIT | MKI_PERMANENT | MKI_MPH_BLINK ); + m.setDisplay(MKI_LIMIT | MKI_PERMANENT ); + // m.setAlert( MKI_TIRE_PRESSURE ); + + // send the data in an endless loop + // every 50ms or so should be enough, + // use pthreads if you want it out of the way + while (1) { + mph++; + temperatur++; + rpm = rpm + 100; + + m.setMph(mph); + m.setDisplayMph(mph); + m.setRpm(rpm); + m.setCWTemp(temperatur); + + m.sendData(); + usleep(100000); + + if(temperatur >= 130) + temperatur = 40; + + if(mph > 160 ) + mph=0; + + if(rpm>6000) + m.setLamps( MKI_WARN_BLINK ); + + if(rpm > 7000) + { + rpm = 0; + m.setLampsOff(); + } + + } + + // everything ok + return 0; +} + +// quick and dirty hack with code from PeakCanLogger +// to allow the interface to be set via commandline. +const char* const fetchinterface (const int argc, const char* const argv[]) +{ + int i, len; + char* interface = new char(5); + strcpy( interface, "can0" ); + + // go through the argument, ignore the first one + for( i = 1; i < argc; i++ ) + { + // check the arguments first and third char, is it a config parameter? + if ( argv[i][0] == '-' ) + { + // check which config parameter it is + switch( argv[i][1] ) + { + // set can-device + case 'd': + case 'f': + // delete the actual char string + delete interface; + + // get the lenght of the new string + len = strlen(&argv[i][3]); + + // create a new one + interface = new char( len ); + + // set string with zeros + memset( interface, 0, len ); + + // and copy it + strcpy( interface, &argv[i][3] ); + + default: + break; + } + } + } + + return interface; +} -- cgit v1.2.3