Merge f7dce28f68
into 342ca8632c
commit
5d83da0205
|
@ -325,7 +325,14 @@ int ecx_FPRD(ecx_portt *port, uint16 ADP, uint16 ADO, uint16 length, void *data,
|
|||
wkc = ecx_srconfirm(port, idx, timeout);
|
||||
if (wkc > 0)
|
||||
{
|
||||
memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length);
|
||||
if (length <= EC_MAXMBX)
|
||||
{
|
||||
memcpy(data, &(port->rxbuf[idx][EC_HEADERSIZE]), length);
|
||||
}
|
||||
else
|
||||
{
|
||||
wkc = EC_ERROR;
|
||||
}
|
||||
}
|
||||
ecx_setbufstat(port, idx, EC_BUF_EMPTY);
|
||||
|
||||
|
|
|
@ -19,8 +19,6 @@
|
|||
#include "ethercatmain.h"
|
||||
#include "ethercatfoe.h"
|
||||
|
||||
#define EC_MAXFOEDATA 512
|
||||
|
||||
/** FOE structure.
|
||||
* Used for Read, Write, Data, Ack and Error mailbox packets.
|
||||
*/
|
||||
|
@ -38,9 +36,9 @@ typedef struct PACKED
|
|||
};
|
||||
union
|
||||
{
|
||||
char FileName[EC_MAXFOEDATA];
|
||||
uint8 Data[EC_MAXFOEDATA];
|
||||
char ErrorText[EC_MAXFOEDATA];
|
||||
char FileName[EC_MAXMBX];
|
||||
uint8 Data[EC_MAXMBX];
|
||||
char ErrorText[EC_MAXMBX];
|
||||
};
|
||||
} ec_FOEt;
|
||||
PACKED_END
|
||||
|
@ -309,13 +307,45 @@ int ecx_FOEwrite(ecx_contextt *context, uint16 slave, char *filename, uint32 pas
|
|||
/* otherwise ignore */
|
||||
if (sendpacket)
|
||||
{
|
||||
if (!psize)
|
||||
{
|
||||
dofinalzero = TRUE;
|
||||
}
|
||||
psize += segmentdata;
|
||||
p = (uint8 *)p - segmentdata;
|
||||
--sendpacket;
|
||||
tsize = psize;
|
||||
if (tsize > maxdata)
|
||||
{
|
||||
tsize = maxdata;
|
||||
}
|
||||
if(tsize || dofinalzero)
|
||||
{
|
||||
worktodo = TRUE;
|
||||
dofinalzero = FALSE;
|
||||
segmentdata = tsize;
|
||||
psize -= segmentdata;
|
||||
/* if last packet was full size, add a zero size packet as final */
|
||||
/* EOF is defined as packetsize < full packetsize */
|
||||
if (!psize && (segmentdata == maxdata))
|
||||
{
|
||||
dofinalzero = TRUE;
|
||||
}
|
||||
FOEp->MbxHeader.length = htoes(0x0006 + segmentdata);
|
||||
FOEp->MbxHeader.address = htoes(0x0000);
|
||||
FOEp->MbxHeader.priority = 0x00;
|
||||
/* get new mailbox count value */
|
||||
cnt = ec_nextmbxcnt(context->slavelist[slave].mbx_cnt);
|
||||
context->slavelist[slave].mbx_cnt = cnt;
|
||||
FOEp->MbxHeader.mbxtype = ECT_MBXT_FOE + (cnt << 4); /* FoE */
|
||||
FOEp->OpCode = ECT_FOE_DATA;
|
||||
sendpacket++;
|
||||
FOEp->PacketNumber = htoel(sendpacket);
|
||||
memcpy(&FOEp->Data[0], p, segmentdata);
|
||||
p = (uint8 *)p + segmentdata;
|
||||
/* send FoE data to slave */
|
||||
wkc = ecx_mbxsend(context, slave, (ec_mbxbuft *)&MbxOut, EC_TIMEOUTTXM);
|
||||
if (wkc <= 0)
|
||||
{
|
||||
worktodo = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
set(SOURCES firm_update.c)
|
||||
add_executable(firm_update ${SOURCES})
|
||||
target_link_libraries(firm_update soem)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(firm_update wpcap.lib Packet.lib Ws2_32.lib Winmm.lib)
|
||||
elseif(UNIX)
|
||||
target_link_libraries(firm_update pthread rt)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "rt-kernel")
|
||||
target_link_libraries(firm_update "-Wl,--start-group -l${BSP} -l${ARCH} -lkern -ldev -lsio -lblock -lfs -lusb -llwip -leth -li2c -lrtc -lcan -lnand -lspi -lnor -lpwm -ladc -ltrace -lc -lm -Wl,--end-group")
|
||||
endif()
|
||||
|
||||
install(TARGETS firm_update DESTINATION bin)
|
|
@ -20,13 +20,13 @@
|
|||
|
||||
#include "ethercat.h"
|
||||
|
||||
#define FWBUFSIZE (8 * 1024 * 1024)
|
||||
#define FWBUFSIZE (20 * 1024 * 1024)
|
||||
|
||||
uint8 ob;
|
||||
uint16 ow;
|
||||
uint32 data;
|
||||
char filename[256];
|
||||
char filebuffer[FWBUFSIZE]; // 8MB buffer
|
||||
char filebuffer[FWBUFSIZE]; // 20MB buffer
|
||||
int filesize;
|
||||
int j;
|
||||
uint16 argslave;
|
||||
|
@ -48,8 +48,9 @@ int input_bin(char *fname, int *length)
|
|||
}
|
||||
|
||||
|
||||
void boottest(char *ifname, uint16 slave, char *filename)
|
||||
int boottest(char *ifname, uint16 slave, char *filename)
|
||||
{
|
||||
int retval = 0;
|
||||
printf("Starting firmware update example\n");
|
||||
|
||||
/* initialise SOEM, bind socket to ifname */
|
||||
|
@ -61,15 +62,47 @@ void boottest(char *ifname, uint16 slave, char *filename)
|
|||
|
||||
if ( ec_config_init(FALSE) > 0 )
|
||||
{
|
||||
int counter = 3;
|
||||
char sm_zero[sizeof(ec_smt)*2];
|
||||
char fmmu_zero[sizeof(ec_fmmut)];
|
||||
unsigned char rd_stat = 0xff;
|
||||
|
||||
memset(sm_zero, 0, sizeof(sm_zero));
|
||||
memset(fmmu_zero, 0, sizeof(fmmu_zero));
|
||||
|
||||
printf("%d slaves found and configured.\n",ec_slavecount);
|
||||
|
||||
counter = 3;
|
||||
do {
|
||||
/* wait for slave to reach PREOP state */
|
||||
if (ec_statecheck(slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE * 4) == EC_STATE_PRE_OP) {
|
||||
printf("Slave is in PREOP state\n");
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
while (counter-- > 0);
|
||||
|
||||
counter = 3;
|
||||
do {
|
||||
printf("Request init state for slave %d\n", slave);
|
||||
ec_slave[slave].state = EC_STATE_INIT;
|
||||
ec_writestate(slave);
|
||||
|
||||
/* wait for slave to reach INIT state */
|
||||
ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE * 4);
|
||||
printf("Slave %d state to INIT.\n", slave);
|
||||
if (ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE * 4) == EC_STATE_INIT)
|
||||
counter = 0;;
|
||||
}
|
||||
while (counter-- > 0);
|
||||
printf("Slave %d state to INIT. counter: %d\n", slave, counter);
|
||||
|
||||
/* clean FMMUs */
|
||||
ec_FPWR(ec_slave[slave].configadr, ECT_REG_FMMU0, sizeof(fmmu_zero), fmmu_zero, EC_TIMEOUTRET3);
|
||||
ec_FPWR(ec_slave[slave].configadr, ECT_REG_FMMU1, sizeof(fmmu_zero), fmmu_zero, EC_TIMEOUTRET3);
|
||||
|
||||
/* clean all SM0 / SM1 to set new bootstrap values later */
|
||||
ec_FPWR(ec_slave[slave].configadr, ECT_REG_SM0, sizeof(ec_smt) * 2, sm_zero, EC_TIMEOUTRET3);
|
||||
ec_FPRD(ec_slave[slave].configadr, ECT_REG_SM1STAT, 1, &rd_stat, EC_TIMEOUTRET3);
|
||||
printf("Read back Status of SM1: %02x\n", rd_stat);
|
||||
|
||||
/* read BOOT mailbox data, master -> slave */
|
||||
data = ec_readeeprom(slave, ECT_SII_BOOTRXMBX, EC_TIMEOUTEEP);
|
||||
|
@ -98,9 +131,24 @@ void boottest(char *ifname, uint16 slave, char *filename)
|
|||
/* program SM1 mailbox out for slave */
|
||||
ec_FPWR (ec_slave[slave].configadr, ECT_REG_SM1, sizeof(ec_smt), &ec_slave[slave].SM[1], EC_TIMEOUTRET);
|
||||
|
||||
printf("Request BOOT state for slave %d\n", slave);
|
||||
ec_slave[slave].state = EC_STATE_BOOT;
|
||||
ec_writestate(slave);
|
||||
/* give EEPROM control to PDI */
|
||||
rd_stat = 1;
|
||||
ec_FPWR (ec_slave[slave].configadr, ECT_REG_EEPCFG, 1, &rd_stat, EC_TIMEOUTRET);
|
||||
|
||||
counter = 3;
|
||||
do {
|
||||
uint16 ret;
|
||||
printf("Request BOOT state for slave %d\n", slave);
|
||||
ec_slave[slave].state = EC_STATE_BOOT;
|
||||
printf("ec_writestate returned: %d\n", ec_writestate(slave));
|
||||
ret = ec_statecheck(slave, EC_STATE_BOOT, EC_TIMEOUTSTATE );
|
||||
printf("ec_statecheck returned: %d\n", ret);
|
||||
if (ret == EC_STATE_BOOT)
|
||||
counter = 0;
|
||||
} while(counter-- > 0);
|
||||
|
||||
printf("check BOOT state again\n");
|
||||
|
||||
|
||||
/* wait for slave to reach BOOT state */
|
||||
if (ec_statecheck(slave, EC_STATE_BOOT, EC_TIMEOUTSTATE * 10) == EC_STATE_BOOT)
|
||||
|
@ -109,22 +157,65 @@ void boottest(char *ifname, uint16 slave, char *filename)
|
|||
|
||||
if (input_bin(filename, &filesize))
|
||||
{
|
||||
char *short_filename = strrchr(filename, '/'); /* search for last / */
|
||||
if (short_filename)
|
||||
short_filename++; /* jump over the \ */
|
||||
else
|
||||
short_filename = filename; /* no \ found -> must be a short filename */
|
||||
printf("File read OK, %d bytes.\n",filesize);
|
||||
printf("FoE write....");
|
||||
j = ec_FOEwrite(slave, filename, 0, filesize , &filebuffer, EC_TIMEOUTSTATE);
|
||||
printf("FoE write %s....\n", short_filename);
|
||||
j = ec_FOEwrite(slave, short_filename, 0, filesize , &filebuffer, EC_TIMEOUTSTATE);
|
||||
printf("result %d.\n",j);
|
||||
printf("Request init state for slave %d\n", slave);
|
||||
ec_slave[slave].state = EC_STATE_INIT;
|
||||
ec_writestate(slave);
|
||||
}
|
||||
else
|
||||
printf("File not read OK.\n");
|
||||
}
|
||||
if (j == 0) retval = 5;
|
||||
else if (j != 1) retval = j;
|
||||
|
||||
if (retval == 0) {
|
||||
/* wait max 600s => 10 minutes for firmware update to complete */
|
||||
counter = 60;
|
||||
retval = 6; /* only success switch to init state afterwards completes firmware update */
|
||||
do {
|
||||
uint16 ret;
|
||||
printf("Request init state for slave %d (counter: %d)\n", slave, counter);
|
||||
ec_slave[slave].state = EC_STATE_INIT;
|
||||
ec_writestate(slave);
|
||||
ret = ec_statecheck(slave, EC_STATE_INIT, 10000000);
|
||||
if (ret == 0) {
|
||||
int count;
|
||||
if ((count = ec_config_init(FALSE)) >= slave) {
|
||||
ec_slave[slave].state = EC_STATE_INIT;
|
||||
ec_writestate(slave);
|
||||
ret = ec_statecheck(slave, EC_STATE_INIT, EC_TIMEOUTSTATE * 10);
|
||||
}
|
||||
else {
|
||||
printf("Slaves found: %d Needed: %d .. will try it again\n", count, slave);
|
||||
#ifndef WIN32
|
||||
sleep(10);
|
||||
#endif
|
||||
ret = 25555;
|
||||
}
|
||||
}
|
||||
if (ret == EC_STATE_INIT) {
|
||||
counter = 0;
|
||||
printf("State change to init success\n");
|
||||
retval = 0;
|
||||
}
|
||||
} while (counter-- > 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("File not read OK.\n");
|
||||
retval = 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Failed to enter boot mode\n");
|
||||
retval = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("No slaves found!\n");
|
||||
retval = 2;
|
||||
}
|
||||
printf("End firmware update example, close socket\n");
|
||||
/* stop SOEM, close socket */
|
||||
|
@ -133,17 +224,20 @@ void boottest(char *ifname, uint16 slave, char *filename)
|
|||
else
|
||||
{
|
||||
printf("No socket connection on %s\nExcecute as root\n",ifname);
|
||||
retval = 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
printf("SOEM (Simple Open EtherCAT Master)\nFirmware update example\n");
|
||||
|
||||
if (argc > 3)
|
||||
{
|
||||
argslave = atoi(argv[2]);
|
||||
boottest(argv[1], argslave, argv[3]);
|
||||
ret = boottest(argv[1], argslave, argv[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -155,5 +249,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
printf("End program\n");
|
||||
return (0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue