1
0
Fork 0

Format some comments including license information.

This commit is contained in:
Janez 2024-07-09 00:49:52 +02:00
parent 90e266ce89
commit 2854ea4a44
12 changed files with 513 additions and 593 deletions

View file

@ -6,21 +6,16 @@
* @author Janez Paternoster * @author Janez Paternoster
* @copyright 2021 Janez Paternoster * @copyright 2021 Janez Paternoster
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CO_APPLICATION_H #ifndef CO_APPLICATION_H
@ -47,8 +42,7 @@ extern "C" {
* *
* @param [in,out] bitRate Stored CAN bit rate, can be overridden. * @param [in,out] bitRate Stored CAN bit rate, can be overridden.
* @param [in,out] nodeId Stored CANopen NodeId, can be overridden. * @param [in,out] nodeId Stored CANopen NodeId, can be overridden.
* @param [out] errInfo Variable may indicate error information - index of * @param [out] errInfo Variable may indicate error information - index of erroneous OD entry.
* erroneous OD entry.
* *
* @return @ref CO_ReturnError_t CO_ERROR_NO in case of success. * @return @ref CO_ReturnError_t CO_ERROR_NO in case of success.
*/ */

View file

@ -7,21 +7,16 @@
* @copyright 2004 - 2015 Janez Paternoster, 2017 - 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2004 - 2015 Janez Paternoster, 2017 - 2020 Neuberger Gebaeudeautomation GmbH
* *
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <string.h> #include <string.h>
@ -55,7 +50,6 @@ static CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
static const uint32_t CO_INVALID_COB_ID = 0xffffffff; static const uint32_t CO_INVALID_COB_ID = 0xffffffff;
/******************************************************************************/
void CO_CANsetIdentToIndex( void CO_CANsetIdentToIndex(
uint32_t *lookup, uint32_t *lookup,
uint32_t index, uint32_t index,
@ -85,7 +79,6 @@ void CO_CANsetIdentToIndex(
} }
/******************************************************************************/
static uint32_t CO_CANgetIndexFromIdent( static uint32_t CO_CANgetIndexFromIdent(
uint32_t *lookup, uint32_t *lookup,
uint32_t ident) uint32_t ident)
@ -101,7 +94,7 @@ static uint32_t CO_CANgetIndexFromIdent(
#endif /* CO_DRIVER_MULTI_INTERFACE */ #endif /* CO_DRIVER_MULTI_INTERFACE */
/** Disable socketCAN rx ******************************************************/ /* Disable socketCAN rx */
static CO_ReturnError_t disableRx(CO_CANmodule_t *CANmodule) static CO_ReturnError_t disableRx(CO_CANmodule_t *CANmodule)
{ {
uint32_t i; uint32_t i;
@ -124,7 +117,7 @@ static CO_ReturnError_t disableRx(CO_CANmodule_t *CANmodule)
} }
/** Set up or update socketCAN rx filters *************************************/ /* Set up or update socketCAN rx filters */
static CO_ReturnError_t setRxFilters(CO_CANmodule_t *CANmodule) static CO_ReturnError_t setRxFilters(CO_CANmodule_t *CANmodule)
{ {
size_t i; size_t i;
@ -167,7 +160,6 @@ static CO_ReturnError_t setRxFilters(CO_CANmodule_t *CANmodule)
} }
/******************************************************************************/
void CO_CANsetConfigurationMode(void *CANptr) void CO_CANsetConfigurationMode(void *CANptr)
{ {
(void)CANptr; (void)CANptr;
@ -175,7 +167,6 @@ void CO_CANsetConfigurationMode(void *CANptr)
} }
/******************************************************************************/
void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule) void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule)
{ {
CO_ReturnError_t ret; CO_ReturnError_t ret;
@ -191,7 +182,6 @@ void CO_CANsetNormalMode(CO_CANmodule_t *CANmodule)
} }
/******************************************************************************/
CO_ReturnError_t CO_CANmodule_init( CO_ReturnError_t CO_CANmodule_init(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
void *CANptr, void *CANptr,
@ -263,7 +253,7 @@ CO_ReturnError_t CO_CANmodule_init(
} }
/** enable socketCAN *********************************************************/ /* enable socketCAN */
#if CO_DRIVER_MULTI_INTERFACE == 0 #if CO_DRIVER_MULTI_INTERFACE == 0
static static
#endif #endif
@ -320,7 +310,7 @@ CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
} }
/* enable software time stamp mode (hardware timestamps do not work properly /* enable software time stamp mode (hardware timestamps do not work properly
* on all devices)*/ * on all devices) */
tmp = (SOF_TIMESTAMPING_SOFTWARE | tmp = (SOF_TIMESTAMPING_SOFTWARE |
SOF_TIMESTAMPING_RX_SOFTWARE); SOF_TIMESTAMPING_RX_SOFTWARE);
ret = setsockopt(interface->fd, SOL_SOCKET, SO_TIMESTAMPING, &tmp, sizeof(tmp)); ret = setsockopt(interface->fd, SOL_SOCKET, SO_TIMESTAMPING, &tmp, sizeof(tmp));
@ -387,7 +377,6 @@ CO_ReturnError_t CO_CANmodule_addInterface(CO_CANmodule_t *CANmodule,
} }
/******************************************************************************/
void CO_CANmodule_disable(CO_CANmodule_t *CANmodule) void CO_CANmodule_disable(CO_CANmodule_t *CANmodule)
{ {
uint32_t i; uint32_t i;
@ -423,7 +412,6 @@ void CO_CANmodule_disable(CO_CANmodule_t *CANmodule)
} }
/******************************************************************************/
CO_ReturnError_t CO_CANrxBufferInit( CO_ReturnError_t CO_CANrxBufferInit(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
uint16_t index, uint16_t index,
@ -477,7 +465,6 @@ CO_ReturnError_t CO_CANrxBufferInit(
#if CO_DRIVER_MULTI_INTERFACE > 0 #if CO_DRIVER_MULTI_INTERFACE > 0
/******************************************************************************/
bool_t CO_CANrxBuffer_getInterface( bool_t CO_CANrxBuffer_getInterface(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
uint16_t ident, uint16_t ident,
@ -514,7 +501,6 @@ bool_t CO_CANrxBuffer_getInterface(
#endif /* CO_DRIVER_MULTI_INTERFACE */ #endif /* CO_DRIVER_MULTI_INTERFACE */
/******************************************************************************/
CO_CANtx_t *CO_CANtxBufferInit( CO_CANtx_t *CO_CANtxBufferInit(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
uint16_t index, uint16_t index,
@ -550,7 +536,6 @@ CO_CANtx_t *CO_CANtxBufferInit(
#if CO_DRIVER_MULTI_INTERFACE > 0 #if CO_DRIVER_MULTI_INTERFACE > 0
/******************************************************************************/
CO_ReturnError_t CO_CANtxBuffer_setInterface( CO_ReturnError_t CO_CANtxBuffer_setInterface(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
uint16_t ident, uint16_t ident,
@ -573,7 +558,7 @@ CO_ReturnError_t CO_CANtxBuffer_setInterface(
#endif /* CO_DRIVER_MULTI_INTERFACE */ #endif /* CO_DRIVER_MULTI_INTERFACE */
#if CO_DRIVER_MULTI_INTERFACE > 0 #if CO_DRIVER_MULTI_INTERFACE > 0
/* send CAN message ***********************************************************/ /* send CAN message */
static CO_ReturnError_t CO_CANCheckSendInterface( static CO_ReturnError_t CO_CANCheckSendInterface(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
CO_CANtx_t *buffer, CO_CANtx_t *buffer,
@ -660,7 +645,6 @@ static CO_ReturnError_t CO_CANCheckSendInterface(
CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer); CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer);
/******************************************************************************/
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer) CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
{ {
CO_ReturnError_t err; CO_ReturnError_t err;
@ -675,7 +659,6 @@ CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
} }
/******************************************************************************/
CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer) CO_ReturnError_t CO_CANCheckSend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
{ {
uint32_t i; uint32_t i;
@ -765,7 +748,6 @@ CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
#endif /* CO_DRIVER_MULTI_INTERFACE == 0 */ #endif /* CO_DRIVER_MULTI_INTERFACE == 0 */
/******************************************************************************/
void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule) void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule)
{ {
(void)CANmodule; (void)CANmodule;
@ -773,7 +755,6 @@ void CO_CANclearPendingSyncPDOs(CO_CANmodule_t *CANmodule)
} }
/******************************************************************************/
void CO_CANmodule_process(CO_CANmodule_t *CANmodule) void CO_CANmodule_process(CO_CANmodule_t *CANmodule)
{ {
if (CANmodule == NULL || CANmodule->CANinterfaceCount == 0) return; if (CANmodule == NULL || CANmodule->CANinterfaceCount == 0) return;
@ -814,7 +795,7 @@ void CO_CANmodule_process(CO_CANmodule_t *CANmodule)
} }
/* Read CAN message from socket and verify some errors ************************/ /* Read CAN message from socket and verify some errors */
static CO_ReturnError_t CO_CANread( static CO_ReturnError_t CO_CANread(
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
CO_CANinterface_t *interface, CO_CANinterface_t *interface,
@ -877,7 +858,7 @@ static CO_ReturnError_t CO_CANread(
} }
/* find msg inside rxArray and call corresponding CANrx_callback **************/ /* find msg inside rxArray and call corresponding CANrx_callback */
static int32_t CO_CANrxMsg( /* return index of received message in rxArray or -1 */ static int32_t CO_CANrxMsg( /* return index of received message in rxArray or -1 */
CO_CANmodule_t *CANmodule, CO_CANmodule_t *CANmodule,
struct can_frame *msg, /* CAN message input */ struct can_frame *msg, /* CAN message input */
@ -923,7 +904,6 @@ static int32_t CO_CANrxMsg( /* return index of received message
} }
/******************************************************************************/
bool_t CO_CANrxFromEpoll(CO_CANmodule_t *CANmodule, bool_t CO_CANrxFromEpoll(CO_CANmodule_t *CANmodule,
struct epoll_event *ev, struct epoll_event *ev,
CO_CANrxMsg_t *buffer, CO_CANrxMsg_t *buffer,

View file

@ -8,21 +8,16 @@
* @copyright 2004 - 2020 Janez Paternoster * @copyright 2004 - 2020 Janez Paternoster
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@ -126,6 +121,15 @@ extern "C" {
CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE) CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE)
#endif #endif
#define CO_CONFIG_GFC (CO_CONFIG_GFC_ENABLE | \
CO_CONFIG_GFC_CONSUMER | \
CO_CONFIG_GFC_PRODUCER)
#define CO_CONFIG_SRDO (CO_CONFIG_SRDO_ENABLE | \
CO_CONFIG_SRDO_CHECK_TX | \
CO_CONFIG_GLOBAL_FLAG_CALLBACK_PRE | \
CO_CONFIG_GLOBAL_FLAG_TIMERNEXT)
#ifndef CO_CONFIG_GTW #ifndef CO_CONFIG_GTW
#define CO_CONFIG_GTW (CO_CONFIG_GTW_ASCII | \ #define CO_CONFIG_GTW (CO_CONFIG_GTW_ASCII | \
CO_CONFIG_GTW_ASCII_SDO | \ CO_CONFIG_GTW_ASCII_SDO | \

View file

@ -8,21 +8,16 @@
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
* *
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
/* following macro is necessary for accept4() function call (sockets) */ /* following macro is necessary for accept4() function call (sockets) */

View file

@ -9,21 +9,16 @@
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
* *
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#ifndef CO_EPOLL_INTERFACE_H #ifndef CO_EPOLL_INTERFACE_H
@ -122,8 +117,7 @@ typedef struct {
* @param ep This object * @param ep This object
* @param timerInterval_us Timer interval in microseconds * @param timerInterval_us Timer interval in microseconds
* *
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or * @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_SYSCALL.
* CO_ERROR_SYSCALL.
*/ */
CO_ReturnError_t CO_epoll_create(CO_epoll_t *ep, uint32_t timerInterval_us); CO_ReturnError_t CO_epoll_create(CO_epoll_t *ep, uint32_t timerInterval_us);
@ -258,8 +252,7 @@ typedef struct {
* @param socketTimeout_ms Timeout for established socket connection in [ms] * @param socketTimeout_ms Timeout for established socket connection in [ms]
* @param localSocketPath File path, if commandInterface is local socket * @param localSocketPath File path, if commandInterface is local socket
* *
* @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or * @return @ref CO_ReturnError_t CO_ERROR_NO, CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_SYSCALL.
* CO_ERROR_SYSCALL.
*/ */
CO_ReturnError_t CO_epoll_createGtw(CO_epoll_gtw_t *epGtw, CO_ReturnError_t CO_epoll_createGtw(CO_epoll_gtw_t *epGtw,
int epoll_fd, int epoll_fd,
@ -302,6 +295,6 @@ void CO_epoll_processGtw(CO_epoll_gtw_t *epGtw,
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /*__cplusplus*/ #endif /* __cplusplus */
#endif /* CO_EPOLL_INTERFACE_H */ #endif /* CO_EPOLL_INTERFACE_H */

View file

@ -6,21 +6,16 @@
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
* *
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <string.h> #include <string.h>
@ -35,7 +30,7 @@
#include "301/CO_driver.h" #include "301/CO_driver.h"
/** /*
* Reset CAN interface and set to listen only mode * Reset CAN interface and set to listen only mode
*/ */
static CO_CANinterfaceState_t CO_CANerrorSetListenOnly( static CO_CANinterfaceState_t CO_CANerrorSetListenOnly(
@ -66,7 +61,7 @@ static CO_CANinterfaceState_t CO_CANerrorSetListenOnly(
} }
/** /*
* Clear listen only * Clear listen only
*/ */
static void CO_CANerrorClearListenOnly( static void CO_CANerrorClearListenOnly(
@ -80,7 +75,7 @@ static void CO_CANerrorClearListenOnly(
} }
/** /*
* Check and handle "bus off" state * Check and handle "bus off" state
*/ */
static CO_CANinterfaceState_t CO_CANerrorBusoff( static CO_CANinterfaceState_t CO_CANerrorBusoff(
@ -104,7 +99,7 @@ static CO_CANinterfaceState_t CO_CANerrorBusoff(
} }
/** /*
* Check and handle controller problems * Check and handle controller problems
*/ */
static CO_CANinterfaceState_t CO_CANerrorCrtl( static CO_CANinterfaceState_t CO_CANerrorCrtl(
@ -165,7 +160,7 @@ static CO_CANinterfaceState_t CO_CANerrorCrtl(
} }
/** /*
* Check and handle controller problems * Check and handle controller problems
*/ */
static CO_CANinterfaceState_t CO_CANerrorNoack( static CO_CANinterfaceState_t CO_CANerrorNoack(
@ -199,7 +194,6 @@ static CO_CANinterfaceState_t CO_CANerrorNoack(
} }
/******************************************************************************/
void CO_CANerror_init( void CO_CANerror_init(
CO_CANinterfaceErrorhandler_t *CANerrorhandler, CO_CANinterfaceErrorhandler_t *CANerrorhandler,
int fd, int fd,
@ -219,7 +213,6 @@ void CO_CANerror_init(
} }
/******************************************************************************/
void CO_CANerror_disable( void CO_CANerror_disable(
CO_CANinterfaceErrorhandler_t *CANerrorhandler) CO_CANinterfaceErrorhandler_t *CANerrorhandler)
{ {
@ -232,7 +225,6 @@ void CO_CANerror_disable(
} }
/******************************************************************************/
void CO_CANerror_rxMsg( void CO_CANerror_rxMsg(
CO_CANinterfaceErrorhandler_t *CANerrorhandler) CO_CANinterfaceErrorhandler_t *CANerrorhandler)
{ {
@ -248,7 +240,6 @@ void CO_CANerror_rxMsg(
} }
/******************************************************************************/
CO_CANinterfaceState_t CO_CANerror_txMsg( CO_CANinterfaceState_t CO_CANerror_txMsg(
CO_CANinterfaceErrorhandler_t *CANerrorhandler) CO_CANinterfaceErrorhandler_t *CANerrorhandler)
{ {
@ -272,7 +263,6 @@ CO_CANinterfaceState_t CO_CANerror_txMsg(
} }
/******************************************************************************/
CO_CANinterfaceState_t CO_CANerror_rxMsgError( CO_CANinterfaceState_t CO_CANerror_rxMsgError(
CO_CANinterfaceErrorhandler_t *CANerrorhandler, CO_CANinterfaceErrorhandler_t *CANerrorhandler,
const struct can_frame *msg) const struct can_frame *msg)

View file

@ -7,21 +7,16 @@
* @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2018 - 2020 Neuberger Gebaeudeautomation GmbH
* *
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
@ -68,8 +63,7 @@ extern "C" {
* openlog ("exampleprog", LOG_PID | LOG_PERROR, LOG_USER); * openlog ("exampleprog", LOG_PID | LOG_PERROR, LOG_USER);
* @endcode * @endcode
* *
* @param priority one of LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, * @param priority one of LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG
* LOG_NOTICE, LOG_INFO, LOG_DEBUG
* @param format format string as in printf * @param format format string as in printf
*/ */
void log_printf(int priority, const char *format, ...); void log_printf(int priority, const char *format, ...);
@ -186,6 +180,6 @@ CO_CANinterfaceState_t CO_CANerror_rxMsgError(
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /*__cplusplus*/ #endif /* __cplusplus */
#endif /* CO_ERROR_H */ #endif /* CO_ERROR_H */

View file

@ -6,21 +6,16 @@
* @copyright 2020 Neuberger Gebaeudeautomation GmbH * @copyright 2020 Neuberger Gebaeudeautomation GmbH
* *
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */

View file

@ -5,21 +5,16 @@
* @author Janez Paternoster * @author Janez Paternoster
* @copyright 2020 Janez Paternoster * @copyright 2020 Janez Paternoster
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <stdio.h> #include <stdio.h>
@ -406,7 +401,7 @@ int main (int argc, char *argv[]) {
CANptr.can_ifindex = if_nametoindex(CANdevice); CANptr.can_ifindex = if_nametoindex(CANdevice);
} }
/* Valid NodeId is 1..127 or 0xFF(unconfigured) in case of LSSslaveEnabled*/ /* Valid NodeId is 1..127 or 0xFF(unconfigured) in case of LSSslaveEnabled */
if ((nodeIdFromArgs == 0 || nodeIdFromArgs > 127) if ((nodeIdFromArgs == 0 || nodeIdFromArgs > 127)
&& (!CO_isLSSslaveEnabled(CO) && (!CO_isLSSslaveEnabled(CO)
|| nodeIdFromArgs != CO_LSS_NODE_ID_ASSIGNMENT) || nodeIdFromArgs != CO_LSS_NODE_ID_ASSIGNMENT)

View file

@ -1,323 +1,318 @@
/* /*
* CANopen data storage object for Linux * CANopen data storage object for Linux
* *
* @file CO_storageLinux.c * @file CO_storageLinux.c
* @author Janez Paternoster * @author Janez Paternoster
* @copyright 2021 Janez Paternoster * @copyright 2021 Janez Paternoster
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>. *
* For more information on CANopen see <http://www.can-cia.org/>. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* * file except in compliance with the License. You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. * http://www.apache.org/licenses/LICENSE-2.0
* You may obtain a copy of the License at *
* * Unless required by applicable law or agreed to in writing, software distributed under the License is
* http://www.apache.org/licenses/LICENSE-2.0 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and limitations under the License.
* Unless required by applicable law or agreed to in writing, software */
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #include "CO_storageLinux.h"
* See the License for the specific language governing permissions and #include "301/crc16-ccitt.h"
* limitations under the License.
*/ #include <stdio.h>
#include <string.h>
#include "CO_storageLinux.h" #include <stdlib.h>
#include "301/crc16-ccitt.h"
#if (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE
#include <stdio.h>
#include <string.h>
#include <stdlib.h> /*
* Function for writing data on "Store parameters" command - OD object 1010
#if (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE *
* For more information see file CO_storage.h, CO_storage_entry_t.
*/
/* static ODR_t storeLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule) {
* Function for writing data on "Store parameters" command - OD object 1010 ODR_t ret = ODR_OK;
* uint16_t crc_store;
* For more information see file CO_storage.h, CO_storage_entry_t.
*/ /* Create names for temporary and old file */
static ODR_t storeLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule) { size_t fn_len = strlen(entry->filename) + 5;
ODR_t ret = ODR_OK; char *filename_tmp = malloc(fn_len);
uint16_t crc_store; char *filename_old = malloc(fn_len);
if (filename_tmp == NULL || filename_old == NULL) {
/* Create names for temporary and old file */ if (filename_tmp != NULL) free(filename_tmp);
size_t fn_len = strlen(entry->filename) + 5; if (filename_old != NULL) free(filename_old);
char *filename_tmp = malloc(fn_len); ret = ODR_OUT_OF_MEM;
char *filename_old = malloc(fn_len); }
if (filename_tmp == NULL || filename_old == NULL) { else {
if (filename_tmp != NULL) free(filename_tmp); strcpy(filename_tmp, entry->filename);
if (filename_old != NULL) free(filename_old); strcpy(filename_old, entry->filename);
ret = ODR_OUT_OF_MEM; strcat(filename_tmp, ".tmp");
} strcat(filename_old, ".old");
else { }
strcpy(filename_tmp, entry->filename);
strcpy(filename_old, entry->filename); /* Open a temporary file and write data to it */
strcat(filename_tmp, ".tmp"); if (ret == ODR_OK) {
strcat(filename_old, ".old"); FILE *fp = fopen(filename_tmp, "w");
} if (fp == NULL) {
ret = ODR_HW;
/* Open a temporary file and write data to it */ }
if (ret == ODR_OK) { else {
FILE *fp = fopen(filename_tmp, "w"); CO_LOCK_OD(CANmodule);
if (fp == NULL) { size_t cnt = fwrite(entry->addr, 1, entry->len, fp);
ret = ODR_HW; crc_store = crc16_ccitt(entry->addr, entry->len, 0);
} CO_UNLOCK_OD(CANmodule);
else { cnt += fwrite(&crc_store, 1, sizeof(crc_store), fp);
CO_LOCK_OD(CANmodule); fclose(fp);
size_t cnt = fwrite(entry->addr, 1, entry->len, fp); if (cnt != (entry->len + sizeof(crc_store))) {
crc_store = crc16_ccitt(entry->addr, entry->len, 0); ret = ODR_HW;
CO_UNLOCK_OD(CANmodule); }
cnt += fwrite(&crc_store, 1, sizeof(crc_store), fp); }
fclose(fp); }
if (cnt != (entry->len + sizeof(crc_store))) {
ret = ODR_HW; /* Verify data */
} if (ret == ODR_OK) {
} uint8_t *buf = NULL;
} FILE *fp = NULL;
size_t cnt = 0;
/* Verify data */ uint16_t crc_verify, crc_read;
if (ret == ODR_OK) {
uint8_t *buf = NULL; buf = malloc(entry->len + 4);
FILE *fp = NULL; if (buf != NULL) {
size_t cnt = 0; fp = fopen(filename_tmp, "r");
uint16_t crc_verify, crc_read; if (fp != NULL) {
cnt = fread(buf, 1, entry->len + 4, fp);
buf = malloc(entry->len + 4); crc_verify = crc16_ccitt(buf, entry->len, 0);
if (buf != NULL) { fclose(fp);
fp = fopen(filename_tmp, "r"); memcpy(&crc_read, &buf[entry->len], sizeof(crc_read));
if (fp != NULL) { }
cnt = fread(buf, 1, entry->len + 4, fp); free(buf);
crc_verify = crc16_ccitt(buf, entry->len, 0); }
fclose(fp); /* If size or CRC differs, report error */
memcpy(&crc_read, &buf[entry->len], sizeof(crc_read)); if (buf == NULL || fp == NULL || cnt != (entry->len+sizeof(crc_verify))
} || crc_store != crc_verify || crc_store != crc_read
free(buf); ) {
} ret = ODR_HW;
/* If size or CRC differs, report error */ }
if (buf == NULL || fp == NULL || cnt != (entry->len+sizeof(crc_verify)) }
|| crc_store != crc_verify || crc_store != crc_read
) { /* rename existing file to *.old and *.tmp to existing */
ret = ODR_HW; if (ret == ODR_OK) {
} rename(entry->filename, filename_old);
} if (rename(filename_tmp, entry->filename) != 0) {
ret = ODR_HW;
/* rename existing file to *.old and *.tmp to existing */ }
if (ret == ODR_OK) { }
rename(entry->filename, filename_old);
if (rename(filename_tmp, entry->filename) != 0) { if (ret != ODR_OUT_OF_MEM) {
ret = ODR_HW; free(filename_tmp);
} free(filename_old);
} }
if (ret != ODR_OUT_OF_MEM) { return ret;
free(filename_tmp); }
free(filename_old);
}
/*
return ret; * Function for restoring data on "Restore default parameters" command - OD 1011
} *
* For more information see file CO_storage.h, CO_storage_entry_t.
*/
/* static ODR_t restoreLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule){
* Function for restoring data on "Restore default parameters" command - OD 1011 (void) CANmodule;
* ODR_t ret = ODR_OK;
* For more information see file CO_storage.h, CO_storage_entry_t.
*/ /* close the file first, if auto storage */
static ODR_t restoreLinux(CO_storage_entry_t *entry, CO_CANmodule_t *CANmodule){ if ((entry->attr & CO_storage_auto) != 0 && entry->fp != NULL) {
(void) CANmodule; fclose(entry->fp);
ODR_t ret = ODR_OK; entry->fp = NULL;
}
/* close the file first, if auto storage */
if ((entry->attr & CO_storage_auto) != 0 && entry->fp != NULL) { /* Rename existing filename to *.old. */
fclose(entry->fp); char *filename_old = malloc(strlen(entry->filename) + 5);
entry->fp = NULL; if (filename_old == NULL) {
} ret = ODR_OUT_OF_MEM;
}
/* Rename existing filename to *.old. */ else {
char *filename_old = malloc(strlen(entry->filename) + 5); strcpy(filename_old, entry->filename);
if (filename_old == NULL) { strcat(filename_old, ".old");
ret = ODR_OUT_OF_MEM; rename(entry->filename, filename_old);
} free(filename_old);
else { }
strcpy(filename_old, entry->filename);
strcat(filename_old, ".old"); /* create an empty file and write "-\n" to it. */
rename(entry->filename, filename_old); if (ret == ODR_OK) {
free(filename_old); FILE *fp = fopen(entry->filename, "w");
} if (fp == NULL) {
ret = ODR_HW;
/* create an empty file and write "-\n" to it. */ }
if (ret == ODR_OK) { else {
FILE *fp = fopen(entry->filename, "w"); fputs("-\n", fp);
if (fp == NULL) { fclose(fp);
ret = ODR_HW; }
} }
else {
fputs("-\n", fp); return ret;
fclose(fp); }
}
}
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
return ret; CO_CANmodule_t *CANmodule,
} OD_entry_t *OD_1010_StoreParameters,
OD_entry_t *OD_1011_RestoreDefaultParam,
CO_storage_entry_t *entries,
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage, uint8_t entriesCount,
CO_CANmodule_t *CANmodule, uint32_t *storageInitError)
OD_entry_t *OD_1010_StoreParameters, {
OD_entry_t *OD_1011_RestoreDefaultParam, CO_ReturnError_t ret;
CO_storage_entry_t *entries,
uint8_t entriesCount, /* verify arguments */
uint32_t *storageInitError) if (storage == NULL || entries == NULL || entriesCount == 0
{ || storageInitError == NULL
CO_ReturnError_t ret; ) {
return CO_ERROR_ILLEGAL_ARGUMENT;
/* verify arguments */ }
if (storage == NULL || entries == NULL || entriesCount == 0
|| storageInitError == NULL storage->enabled = false;
) {
return CO_ERROR_ILLEGAL_ARGUMENT; /* initialize storage and OD extensions */
} ret = CO_storage_init(storage,
CANmodule,
storage->enabled = false; OD_1010_StoreParameters,
OD_1011_RestoreDefaultParam,
/* initialize storage and OD extensions */ storeLinux,
ret = CO_storage_init(storage, restoreLinux,
CANmodule, entries,
OD_1010_StoreParameters, entriesCount);
OD_1011_RestoreDefaultParam, if (ret != CO_ERROR_NO) {
storeLinux, return ret;
restoreLinux, }
entries,
entriesCount); /* initialize entries */
if (ret != CO_ERROR_NO) { *storageInitError = 0;
return ret; for (uint8_t i = 0; i < entriesCount; i++) {
} CO_storage_entry_t *entry = &entries[i];
bool_t dataCorrupt = false;
/* initialize entries */ char *writeFileAccess = "w";
*storageInitError = 0;
for (uint8_t i = 0; i < entriesCount; i++) { /* verify arguments */
CO_storage_entry_t *entry = &entries[i]; if (entry->addr == NULL || entry->len == 0 || entry->subIndexOD < 2
bool_t dataCorrupt = false; || strlen(entry->filename) == 0
char *writeFileAccess = "w"; ) {
*storageInitError = i;
/* verify arguments */ return CO_ERROR_ILLEGAL_ARGUMENT;
if (entry->addr == NULL || entry->len == 0 || entry->subIndexOD < 2 }
|| strlen(entry->filename) == 0
) { /* Open file, check existence and create temporary buffer */
*storageInitError = i; uint8_t *buf = NULL;
return CO_ERROR_ILLEGAL_ARGUMENT; FILE * fp = fopen(entry->filename, "r");
} if (fp == NULL) {
dataCorrupt = true;
/* Open file, check existence and create temporary buffer */ ret = CO_ERROR_DATA_CORRUPT;
uint8_t *buf = NULL; }
FILE * fp = fopen(entry->filename, "r"); else {
if (fp == NULL) { buf = malloc(entry->len + sizeof(uint16_t));
dataCorrupt = true; if (buf == NULL) {
ret = CO_ERROR_DATA_CORRUPT; fclose(fp);
} *storageInitError = i;
else { return CO_ERROR_OUT_OF_MEMORY;
buf = malloc(entry->len + sizeof(uint16_t)); }
if (buf == NULL) { }
fclose(fp);
*storageInitError = i; /* Read data into temporary buffer first. Then verify and copy to addr */
return CO_ERROR_OUT_OF_MEMORY; if (!dataCorrupt) {
} size_t cnt = fread(buf, 1, entry->len + sizeof(uint16_t), fp);
}
/* If file is empty, just skip loading, default values will be used,
/* Read data into temporary buffer first. Then verify and copy to addr*/ * no error. Otherwise verify length and crc and copy data. */
if (!dataCorrupt) { if (!(cnt == 2 && buf[0] == '-')) {
size_t cnt = fread(buf, 1, entry->len + sizeof(uint16_t), fp); uint16_t crc1, crc2;
crc1 = crc16_ccitt(buf, entry->len, 0);
/* If file is empty, just skip loading, default values will be used, memcpy(&crc2, &buf[entry->len], sizeof(crc2));
* no error. Otherwise verify length and crc and copy data. */
if (!(cnt == 2 && buf[0] == '-')) { if (crc1 == crc2 && cnt == (entry->len + sizeof(crc2))) {
uint16_t crc1, crc2; memcpy(entry->addr, buf, entry->len);
crc1 = crc16_ccitt(buf, entry->len, 0); entry->crc = crc1;
memcpy(&crc2, &buf[entry->len], sizeof(crc2)); writeFileAccess = "r+";
}
if (crc1 == crc2 && cnt == (entry->len + sizeof(crc2))) { else {
memcpy(entry->addr, buf, entry->len); dataCorrupt = true;
entry->crc = crc1; ret = CO_ERROR_DATA_CORRUPT;
writeFileAccess = "r+"; }
} }
else {
dataCorrupt = true; free(buf);
ret = CO_ERROR_DATA_CORRUPT; fclose(fp);
} }
}
/* additional info in case of error */
free(buf); if (dataCorrupt) {
fclose(fp); uint32_t errorBit = entry->subIndexOD;
} if (errorBit > 31) errorBit = 31;
*storageInitError |= ((uint32_t) 1) << errorBit;
/* additional info in case of error */ }
if (dataCorrupt) {
uint32_t errorBit = entry->subIndexOD; /* open file for auto storage, if set so */
if (errorBit > 31) errorBit = 31; if ((entry->attr & CO_storage_auto) != 0) {
*storageInitError |= ((uint32_t) 1) << errorBit; entry->fp = fopen(entry->filename, writeFileAccess);
} if (entry->fp == NULL) {
*storageInitError = i;
/* open file for auto storage, if set so */ return CO_ERROR_ILLEGAL_ARGUMENT;
if ((entry->attr & CO_storage_auto) != 0) { }
entry->fp = fopen(entry->filename, writeFileAccess); }
if (entry->fp == NULL) { } /* for (entries) */
*storageInitError = i;
return CO_ERROR_ILLEGAL_ARGUMENT; storage->enabled = true;
} return ret;
} }
} /* for (entries) */
storage->enabled = true; uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
return ret; bool_t closeFiles)
} {
uint32_t storageError = 0;
uint32_t CO_storageLinux_auto_process(CO_storage_t *storage, /* verify arguments */
bool_t closeFiles) if (storage == NULL) {
{ return false;
uint32_t storageError = 0; }
/* verify arguments */ /* loop through entries */
if (storage == NULL) { for (uint8_t i = 0; i < storage->entriesCount; i++) {
return false; CO_storage_entry_t *entry = &storage->entries[i];
}
if ((entry->attr & CO_storage_auto) == 0 || entry->fp == NULL)
/* loop through entries */ continue;
for (uint8_t i = 0; i < storage->entriesCount; i++) {
CO_storage_entry_t *entry = &storage->entries[i]; /* If CRC of the current data differs, save the file */
uint16_t crc = crc16_ccitt(entry->addr, entry->len, 0);
if ((entry->attr & CO_storage_auto) == 0 || entry->fp == NULL) if (crc != entry->crc) {
continue; size_t cnt;
rewind(entry->fp);
/* If CRC of the current data differs, save the file */ CO_LOCK_OD(storage->CANmodule);
uint16_t crc = crc16_ccitt(entry->addr, entry->len, 0); cnt = fwrite(entry->addr, 1, entry->len, entry->fp);
if (crc != entry->crc) { CO_UNLOCK_OD(storage->CANmodule);
size_t cnt; cnt += fwrite(&crc, 1, sizeof(crc), entry->fp);
rewind(entry->fp); fflush(entry->fp);
CO_LOCK_OD(storage->CANmodule); if (cnt == (entry->len + sizeof(crc))) {
cnt = fwrite(entry->addr, 1, entry->len, entry->fp); entry->crc = crc;
CO_UNLOCK_OD(storage->CANmodule); }
cnt += fwrite(&crc, 1, sizeof(crc), entry->fp); else {
fflush(entry->fp); /* error with save */
if (cnt == (entry->len + sizeof(crc))) { uint32_t errorBit = entry->subIndexOD;
entry->crc = crc; if (errorBit > 31) errorBit = 31;
} storageError |= ((uint32_t) 1) << errorBit;
else { }
/* error with save */ }
uint32_t errorBit = entry->subIndexOD;
if (errorBit > 31) errorBit = 31; if (closeFiles) {
storageError |= ((uint32_t) 1) << errorBit; fclose(entry->fp);
} entry->fp = NULL;
} }
}
if (closeFiles) {
fclose(entry->fp); return storageError;
entry->fp = NULL; }
}
} #endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
return storageError;
}
#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */

View file

@ -1,108 +1,99 @@
/** /**
* CANopen data storage object for Linux * CANopen data storage object for Linux
* *
* @file CO_storageLinux.h * @file CO_storageLinux.h
* @ingroup CO_storageLinux * @ingroup CO_storageLinux
* @author Janez Paternoster * @author Janez Paternoster
* @copyright 2021 Janez Paternoster * @copyright 2021 Janez Paternoster
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>. *
* For more information on CANopen see <http://www.can-cia.org/>. * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* * file except in compliance with the License. You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. * http://www.apache.org/licenses/LICENSE-2.0
* You may obtain a copy of the License at *
* * Unless required by applicable law or agreed to in writing, software distributed under the License is
* http://www.apache.org/licenses/LICENSE-2.0 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and limitations under the License.
* Unless required by applicable law or agreed to in writing, software */
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #ifndef CO_STORAGE_LINUX_H
* See the License for the specific language governing permissions and #define CO_STORAGE_LINUX_H
* limitations under the License.
*/ #include "storage/CO_storage.h"
#ifndef CO_STORAGE_LINUX_H #if ((CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN
#define CO_STORAGE_LINUX_H
#ifdef __cplusplus
#include "storage/CO_storage.h" extern "C" {
#endif
#if ((CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE) || defined CO_DOXYGEN
/**
#ifdef __cplusplus * @defgroup CO_storageLinux Data storage with Linux
extern "C" { * Data initialize, store and restore functions with Linux.
#endif *
* @ingroup CO_socketCAN
/** * @{
* @defgroup CO_storageLinux Data storage with Linux *
* Data initialize, store and restore functions with Linux. * See also @ref CO_storage.
* */
* @ingroup CO_socketCAN
* @{
* /**
* See also @ref CO_storage. * Initialize data storage object (Linux specific)
*/ *
* This function should be called by application after the program startup,
* before @ref CO_CANopenInit(). This function initializes storage object,
/** * OD extensions on objects 1010 and 1011, reads data from file, verifies them
* Initialize data storage object (Linux specific) * and writes data to addresses specified inside entries. This function
* * internally calls @ref CO_storage_init().
* This function should be called by application after the program startup, *
* before @ref CO_CANopenInit(). This function initializes storage object, * @param storage This object will be initialized. It must be defined by application and must exist permanently.
* OD extensions on objects 1010 and 1011, reads data from file, verifies them * @param CANmodule CAN device, used for @ref CO_LOCK_OD() macro.
* and writes data to addresses specified inside entries. This function * @param OD_1010_StoreParameters OD entry for 0x1010 -"Store parameters". Entry is optional, may be NULL.
* internally calls @ref CO_storage_init(). * @param OD_1011_RestoreDefaultParam OD entry for 0x1011 -"Restore default
* * parameters". Entry is optional, may be NULL.
* @param storage This object will be initialized. It must be defined by * @param entries Pointer to array of storage entries, see @ref CO_storage_init.
* application and must exist permanently. * @param entriesCount Count of storage entries
* @param CANmodule CAN device, used for @ref CO_LOCK_OD() macro. * @param [out] storageInitError If function returns CO_ERROR_DATA_CORRUPT,
* @param OD_1010_StoreParameters OD entry for 0x1010 -"Store parameters". * then this variable contains a bit mask from subIndexOD values, where data
* Entry is optional, may be NULL. * was not properly initialized. If other error, then this variable contains
* @param OD_1011_RestoreDefaultParam OD entry for 0x1011 -"Restore default * index or erroneous entry.
* parameters". Entry is optional, may be NULL. *
* @param entries Pointer to array of storage entries, see @ref CO_storage_init. * @return CO_ERROR_NO, CO_ERROR_DATA_CORRUPT if data can not be initialized,
* @param entriesCount Count of storage entries * CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_OUT_OF_MEMORY.
* @param [out] storageInitError If function returns CO_ERROR_DATA_CORRUPT, */
* then this variable contains a bit mask from subIndexOD values, where data CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
* was not properly initialized. If other error, then this variable contains CO_CANmodule_t *CANmodule,
* index or erroneous entry. OD_entry_t *OD_1010_StoreParameters,
* OD_entry_t *OD_1011_RestoreDefaultParam,
* @return CO_ERROR_NO, CO_ERROR_DATA_CORRUPT if data can not be initialized, CO_storage_entry_t *entries,
* CO_ERROR_ILLEGAL_ARGUMENT or CO_ERROR_OUT_OF_MEMORY. uint8_t entriesCount,
*/ uint32_t *storageInitError);
CO_ReturnError_t CO_storageLinux_init(CO_storage_t *storage,
CO_CANmodule_t *CANmodule,
OD_entry_t *OD_1010_StoreParameters, /**
OD_entry_t *OD_1011_RestoreDefaultParam, * Automatically save data if differs from previous call.
CO_storage_entry_t *entries, *
uint8_t entriesCount, * Should be called cyclically by program. Each interval it verifies, if crc
uint32_t *storageInitError); * checksum of data differs from previous checksum. If it does, data are saved
* into pre-opened file.
*
/** * @param storage This object
* Automatically save data if differs from previous call. * @param closeFiles If true, then all files will be closed. Use on end of the program.
* *
* Should be called cyclically by program. Each interval it verifies, if crc * @return 0 on success or bit mask from subIndexOD values, where data was not able to be saved.
* checksum of data differs from previous checksum. If it does, data are saved */
* into pre-opened file. uint32_t CO_storageLinux_auto_process(CO_storage_t *storage,
* bool_t closeFiles);
* @param storage This object
* @param closeFiles If true, then all files will be closed. Use on end of the /** @} */ /* CO_storageLinux */
* program.
* #ifdef __cplusplus
* @return 0 on success or bit mask from subIndexOD values, where data was not }
* able to be saved. #endif /* __cplusplus */
*/
uint32_t CO_storageLinux_auto_process(CO_storage_t *storage, #endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
bool_t closeFiles);
#endif /* CO_STORAGE_LINUX_H */
/** @} */ /* CO_storageLinux */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* (CO_CONFIG_STORAGE) & CO_CONFIG_STORAGE_ENABLE */
#endif /* CO_STORAGE_LINUX_H */

View file

@ -5,21 +5,16 @@
* @author Janez Paternoster * @author Janez Paternoster
* @copyright 2020 Janez Paternoster * @copyright 2020 Janez Paternoster
* *
* This file is part of CANopenNode, an opensource CANopen Stack. * This file is part of <https://github.com/CANopenNode/CANopenNode>, a CANopen Stack.
* Project home page is <https://github.com/CANopenNode/CANopenNode>.
* For more information on CANopen see <http://www.can-cia.org/>.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* you may not use this file except in compliance with the License. * file except in compliance with the License. You may obtain a copy of the License at
* You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software distributed under the License is
* distributed under the License is distributed on an "AS IS" BASIS, * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
#include <stdio.h> #include <stdio.h>
@ -101,14 +96,14 @@ static int printReply(int fd_gtw) {
} }
for (;;) { for (;;) {
ssize_t nRead = read(fd_gtw, &replyBuf[count], BUF_SIZE); /* blocking*/ ssize_t nRead = read(fd_gtw, &replyBuf[count], BUF_SIZE); /* blocking */
if(nRead > 0) { if(nRead > 0) {
count += nRead; count += nRead;
replyBuf[count] = 0; replyBuf[count] = 0;
if (firstPass == 1) { if (firstPass == 1) {
/* check for response type. Only response value goes to stdout*/ /* check for response type. Only response value goes to stdout */
if (strstr(replyBuf, "] ERROR:") != NULL if (strstr(replyBuf, "] ERROR:") != NULL
&& strstr(replyBuf, "\r\n") != NULL && strstr(replyBuf, "\r\n") != NULL
) { ) {
@ -198,7 +193,6 @@ static int printReply(int fd_gtw) {
} }
/******************************************************************************/
int main (int argc, char *argv[]) { int main (int argc, char *argv[]) {
/* configurable options */ /* configurable options */
enum {out_all, out_data, out_flat} outputType = out_all; enum {out_all, out_data, out_flat} outputType = out_all;
@ -357,7 +351,7 @@ int main (int argc, char *argv[]) {
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
else { // addrFamily == AF_UNIX else { /* addrFamily == AF_UNIX */
fd_gtw = socket(AF_UNIX, SOCK_STREAM, 0); fd_gtw = socket(AF_UNIX, SOCK_STREAM, 0);
if(fd_gtw == -1) { if(fd_gtw == -1) {
perror("Socket creation failed"); perror("Socket creation failed");
@ -429,14 +423,14 @@ int main (int argc, char *argv[]) {
size_t len = strlen(commBuf); size_t len = strlen(commBuf);
if (len < 1) continue; if (len < 1) continue;
// send command /* send command */
if (write(fd_gtw, commBuf, len) != len) { /* blocking function */ if (write(fd_gtw, commBuf, len) != len) { /* blocking function */
perror("Socket write failed"); perror("Socket write failed");
free(commBuf); free(commBuf);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// print reply, if command is complete /* print reply, if command is complete */
if (commBuf[len - 1] == '\n') { if (commBuf[len - 1] == '\n') {
if (printReply(fd_gtw) == EXIT_FAILURE) { if (printReply(fd_gtw) == EXIT_FAILURE) {
ret = EXIT_FAILURE; ret = EXIT_FAILURE;
@ -489,7 +483,7 @@ int main (int argc, char *argv[]) {
if (len < BUF_SIZE-2 && lastChar != '\n') if (len < BUF_SIZE-2 && lastChar != '\n')
continue; continue;
// send command /* send command */
if (write(fd_gtw, commBuf, len) != len) { /* blocking f. */ if (write(fd_gtw, commBuf, len) != len) { /* blocking f. */
perror("Socket write failed"); perror("Socket write failed");
free(commBuf); free(commBuf);
@ -513,14 +507,14 @@ int main (int argc, char *argv[]) {
size_t len = strlen(commBuf); size_t len = strlen(commBuf);
if (len < 1) continue; if (len < 1) continue;
// send command /* send command */
if (write(fd_gtw, commBuf, len) != len) { /* blocking function */ if (write(fd_gtw, commBuf, len) != len) { /* blocking function */
perror("Socket write failed"); perror("Socket write failed");
free(commBuf); free(commBuf);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
// print reply, if command is complete /* print reply, if command is complete */
if (commBuf[len - 1] == '\n') { if (commBuf[len - 1] == '\n') {
if (printReply(fd_gtw) == EXIT_FAILURE) { if (printReply(fd_gtw) == EXIT_FAILURE) {
ret = EXIT_FAILURE; ret = EXIT_FAILURE;