LPCtarget/plc_LPC_main.c
author Laurent Bessard
Tue, 19 Mar 2013 23:19:43 +0100
changeset 30 9cd6bc93ed89
parent 29 86fb7dc2b54e
child 31 a9c9d1fc97d3
permissions -rwxr-xr-x
Fixed support for logging and simulation
/**
 * LPC specific code
 **/

#include <string.h>
#include <app_glue.h>

extern unsigned long idLen;
extern unsigned char *idBuf;

static unsigned char RetainedIdBuf[128] NONVOLATILE;
static unsigned char retain_buffer[RETAIN_BUFFER_SIZE] NONVOLATILE;

#define LOG_BUFFER_SIZE (1<<10) /*1Ko*/
#define LOG_BUFFER_ATTRS NONVOLATILE

static int debug_locked = 0;
static int _DebugDataAvailable = 0;
static unsigned long __debug_tick;

void LPC_GetTime(IEC_TIME*);
void LPC_SetTimer(unsigned long long next, unsigned long long period);

long AtomicCompareExchange(long* atomicvar,long compared, long exchange)
{
	/* No need for real atomic op on LPC,
	 * no possible preemption between debug and PLC */
	long res = *atomicvar;
	if(res == compared){
		*atomicvar = exchange;
	}
	return res;
}

long AtomicCompareExchange64(long long* atomicvar,long long compared, long long exchange)
{
	/* No need for real atomic op on LPC,
	 * no possible preemption between debug and PLC */
	long long res = *atomicvar;
	if(res == compared){
		*atomicvar = exchange;
	}
	return res;
}


void PLC_GetTime(IEC_TIME *CURRENT_TIME)
{
	/* Call target GetTime function */
	LPC_GetTime(CURRENT_TIME);
}

void PLC_SetTimer(unsigned long long next, unsigned long long period)
{
	LPC_SetTimer(next, period);
}

int startPLC(int argc,char **argv)
{
	if(__init(argc,argv) == 0){
		PLC_SetTimer(0, Ttick);
		return 0;
	}else{
		return 1;
	}
}

int TryEnterDebugSection(void)
{
    if(!debug_locked && __DEBUG){
        debug_locked = 1;
		return 1;
    }
    return 0;
}

void LeaveDebugSection(void)
{
        debug_locked = 0;
}

int stopPLC(void)
{
    __cleanup();
    return 0;
}

/* from plc_debugger.c */
int WaitDebugData(unsigned long *tick)
{
    /* no blocking call on LPC */
    if(_DebugDataAvailable && !debug_locked){
        /* returns 0 on success */
        *tick = __debug_tick;
        _DebugDataAvailable = 0;
        return 0;
    }
    return 1;
}

/* Called by PLC thread when debug_publish finished
 * This is supposed to unlock debugger thread in WaitDebugData*/
void InitiateDebugTransfer(void)
{
    /* remember tick */
    __debug_tick = __tick;
    _DebugDataAvailable = 1;
}

void suspendDebug(int disable)
{
    /* Prevent PLC to enter debug code */
    __DEBUG = !disable;
    debug_locked = !disable;
}

void resumeDebug(void)
{
    /* Let PLC enter debug code */
    __DEBUG = 1;
    debug_locked = 0;
}

void ValidateRetainBuffer(void)
{
        memcpy(RetainedIdBuf, idBuf, idLen);
}

void InValidateRetainBuffer(void)
{
    /* invalidate that buffer */
    RetainedIdBuf[0] = 0;
}

int CheckRetainBuffer(void)
{
	/* compare RETAIN ID buffer with MD5 */
    /* return true if identical */
    int res = memcmp(RetainedIdBuf, idBuf, idLen) == 0;
    return res;
}

void Retain(unsigned int offset, unsigned int count, void *p)
{
    if(offset + count < RETAIN_BUFFER_SIZE)
        /* write in RETAIN buffer at offset*/
        memcpy(&retain_buffer[offset], p, count);
}

void Remind(unsigned int offset, unsigned int count, void *p)
{
    if(offset + count < RETAIN_BUFFER_SIZE)
        /* read at offset in RETAIN buffer */
        memcpy(p, &retain_buffer[offset], count);
}