1
0
Fork 0
CANopenNode/example/eeprom.c
Freddie Chopin 4c3011d34a
Replace all memcpy/memset-like functions with standard <string.h> functions (#175)
* Use standard memcpy() instead of CO_memcpy()

* Remove CO_memcpy()

* Use standard memset() instead of CO_memset()

* Remove CO_memset()

* Move helper functions from CO_SDOserver.c to header and make them inline

* Implement CO_getUint16() with memcpy()

* Implement CO_getUint32() with memcpy()

* Implement CO_setUint16() with memcpy()

* Implement CO_setUint32() with memcpy()

* Define memcpy() as CO_memcpySwapX() for little-endian systems

* Fix several writes past the buffer due to hardcoded sizes

Use more "generic" sizes (via sizeof()) instead of hardcoded number in
all calls to memset() to avoid 1-byte errors which result in writes past
the buffer, for example:

memset(&LSSslave->TXbuff->data[5], 0, 4);
in CO_LSSslave_serviceInquire()

memset(&LSSmaster->TXbuff->data[6], 0, 3);
in CO_LSSmaster_switchStateSelectInitiate()

* Use "generic" size in calls to memcpy() where possible

* Remove CO_bytes_t

This type was used only for CO_{get,set}Uint{16,32}().
2020-05-04 11:22:32 +02:00

176 lines
5.1 KiB
C

/**
* Microcontroller specific code for CANopenNode nonvolatile variables.
*
* This file is a template for other microcontrollers.
*
* @file eeprom.h
* @ingroup CO_eeprom
* @author Janez Paternoster
* @copyright 2004 - 2020 Janez Paternoster
*
* This file is part of CANopenNode, an opensource 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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "301/CO_driver.h"
#include "301/CO_SDOserver.h"
#include "301/CO_Emergency.h"
#include "301/crc16-ccitt.h"
#include "eeprom.h"
/**
* OD function for accessing _Store parameters_ (index 0x1010) from SDO server.
*
* For more information see file CO_SDOserver.h.
*/
static CO_SDO_abortCode_t CO_ODF_1010(CO_ODF_arg_t *ODF_arg);
static CO_SDO_abortCode_t CO_ODF_1010(CO_ODF_arg_t *ODF_arg){
//CO_EE_t *ee;
uint32_t value;
CO_SDO_abortCode_t ret = CO_SDO_AB_NONE;
//ee = (CO_EE_t*) ODF_arg->object;
value = CO_getUint32(ODF_arg->data);
if(!ODF_arg->reading){
/* don't change the old value */
memcpy(ODF_arg->data, ODF_arg->ODdataStorage, 4);
if(ODF_arg->subIndex == 1U){
if(value == 0x65766173UL){
/* write ee->OD_ROMAddress, ee->OD_ROMSize to eeprom (blocking function) */
/* verify data */
if(0/*error*/){
ret = CO_SDO_AB_HW;
}
}
else{
ret = CO_SDO_AB_DATA_TRANSF;
}
}
}
return ret;
}
/**
* OD function for accessing _Restore default parameters_ (index 0x1011) from SDO server.
*
* For more information see file CO_SDOserver.h.
*/
static CO_SDO_abortCode_t CO_ODF_1011(CO_ODF_arg_t *ODF_arg);
static CO_SDO_abortCode_t CO_ODF_1011(CO_ODF_arg_t *ODF_arg){
//CO_EE_t *ee;
uint32_t value;
CO_SDO_abortCode_t ret = CO_SDO_AB_NONE;
//ee = (CO_EE_t*) ODF_arg->object;
value = CO_getUint32(ODF_arg->data);
if(!ODF_arg->reading){
/* don't change the old value */
memcpy(ODF_arg->data, ODF_arg->ODdataStorage, 4);
if(ODF_arg->subIndex >= 1U){
if(value == 0x64616F6CUL){
/* Clear the eeprom */
}
else{
ret = CO_SDO_AB_DATA_TRANSF;
}
}
}
return ret;
}
/******************************************************************************/
CO_ReturnError_t CO_EE_init_1(
CO_EE_t *ee,
uint8_t *OD_EEPROMAddress,
uint32_t OD_EEPROMSize,
uint8_t *OD_ROMAddress,
uint32_t OD_ROMSize)
{
/* verify arguments */
if(ee==NULL || OD_EEPROMAddress==NULL || OD_ROMAddress==NULL){
return CO_ERROR_ILLEGAL_ARGUMENT;
}
/* Configure eeprom */
/* configure object variables */
ee->OD_EEPROMAddress = OD_EEPROMAddress;
ee->OD_EEPROMSize = OD_EEPROMSize;
ee->OD_ROMAddress = OD_ROMAddress;
ee->OD_ROMSize = OD_ROMSize;
ee->OD_EEPROMCurrentIndex = 0U;
ee->OD_EEPROMWriteEnable = false;
/* read the CO_OD_EEPROM from EEPROM, first verify, if data are OK */
/* read the CO_OD_ROM from EEPROM and verify CRC */
return CO_ERROR_NO;
}
/******************************************************************************/
void CO_EE_init_2(
CO_EE_t *ee,
CO_ReturnError_t eeStatus,
CO_SDO_t *SDO,
CO_EM_t *em)
{
CO_OD_configure(SDO, OD_H1010_STORE_PARAM_FUNC, CO_ODF_1010, (void*)ee, 0, 0U);
CO_OD_configure(SDO, OD_H1011_REST_PARAM_FUNC, CO_ODF_1011, (void*)ee, 0, 0U);
if(eeStatus != CO_ERROR_NO){
CO_errorReport(em, CO_EM_NON_VOLATILE_MEMORY, CO_EMC_HARDWARE, (uint32_t)eeStatus);
}
}
/******************************************************************************/
void CO_EE_process(CO_EE_t *ee){
if((ee != 0) && (ee->OD_EEPROMWriteEnable)/* && !isWriteInProcess()*/){
uint32_t i;
uint8_t RAMdata, eeData;
/* verify next word */
if(++ee->OD_EEPROMCurrentIndex == ee->OD_EEPROMSize){
ee->OD_EEPROMCurrentIndex = 0U;
}
i = ee->OD_EEPROMCurrentIndex;
/* read eeprom */
RAMdata = ee->OD_EEPROMAddress[i];
eeData = 0/*EE_readByte(i)*/;
/* if bytes in EEPROM and in RAM are different, then write to EEPROM */
if(eeData != RAMdata){
/* EE_writeByteNoWait(RAMdata, i);*/
}
}
}