New Module: faultlog

dev-top
Harald Wolff 2017-11-20 13:56:43 +01:00
parent ea7b22b4eb
commit 14dc23f8d5
3 changed files with 159 additions and 0 deletions

View File

@ -0,0 +1,2 @@
DEPENDS+=../core

View File

@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
typedef struct {
uint32_t tcOnPower;
uint32_t tcRun;
union {
uint32_t ui32;
struct {
uint8_t fault_code;
};
};
int32_t parm1;
int32_t parm2;
} fault_entry_t;
void init_faultlog(void);
void faultlog_record(uint8_t faultcode,int32_t parm1,int32_t parm2);
int flog_node_proc(int op,int regno,uint8_t *type,void *buffer);

View File

@ -0,0 +1,134 @@
#include <faultlog/faultlog.h>
#include <rb2/regbus.h>
#include <sys/errno.h>
#include <sys/i2ceeprom.h>
#include <sys/runtime.h>
#include <sys/types.h>
#include <sys/trace.h>
#if !defined(FAULTLOG_EEBASE)
#define FAULTLOG_EEBASE 0x0000
#endif
#if !defined(FAULTLOG_WIDTH)
#define FAULTLOG_WIDTH 9
#endif
static int32_t flog_base = FAULTLOG_EEBASE;
static int flog_width = FAULTLOG_WIDTH;
static int flog_current = 0;
static int flog_current_rd;
static fault_entry_t
current_fault_entry;
static fault_entry_t
current_fault_entry_rd;
void init_faultlog(void)
{
uint16_t n;
uint32_t lastOnPower = 0;
for (n=0;n < (1<<FAULTLOG_WIDTH); n++){
trace_swap( 3 );
if (i2cee_load( flog_base + (n * sizeof(fault_entry_t)), &current_fault_entry, sizeof(fault_entry_t) ) < 0){
flog_width = 0;
} else if (
(current_fault_entry.tcOnPower == 0xFFFFFFFFl) ||
(lastOnPower > current_fault_entry.tcOnPower)
){
flog_current = n;
break;
};
};
};
void faultlog_record(uint8_t faultcode,int32_t parm1,int32_t parm2)
{
current_fault_entry.tcOnPower = rt_ram.eeprom.secs_powered;
current_fault_entry.tcRun = rt_ram.eeprom.secs_running;
current_fault_entry.fault_code = faultcode;
current_fault_entry.parm1 = parm1;
current_fault_entry.parm2 = parm2;
i2cee_save( flog_base + (flog_current * sizeof(fault_entry_t)), &current_fault_entry, sizeof(fault_entry_t) );
flog_current++;
flog_current &= (1<<flog_width)-1;
};
int flog_node_proc(int op,int regno,uint8_t *type,void *buffer){
int i;
if (!IN_LIMITS(regno,0x0500,0x057F)){
return -1;
};
switch (op & RNPOP_MASK){
case RNPOP_READ:
switch (regno){
case 0x0500:
*(int32_t*)buffer = flog_base;
return ESUCCESS;
case 0x0501:
*(int32_t*)buffer = flog_width;
return ESUCCESS;
case 0x0502:
*(int32_t*)buffer = flog_current;
return ESUCCESS;
case 0x0503:
*(int32_t*)buffer = flog_current_rd;
return ESUCCESS;
case 0x0504:
*(int32_t*)buffer = 0;
return ESUCCESS;
case 0x0505:
*(int32_t*)buffer = 0;
return ESUCCESS;
case 0x0506:
*(int32_t*)buffer = 0;
return ESUCCESS;
case 0x0507:
*(int32_t*)buffer = 0;
return ESUCCESS;
case 0x0510:
*(int32_t*)buffer = current_fault_entry_rd.tcOnPower;
return ESUCCESS;
case 0x0511:
*(int32_t*)buffer = current_fault_entry_rd.tcRun;
return ESUCCESS;
case 0x0512:
*(int32_t*)buffer = current_fault_entry_rd.ui32;
return ESUCCESS;
case 0x0513:
*(int32_t*)buffer = current_fault_entry_rd.parm1;
return ESUCCESS;
case 0x0514:
*(int32_t*)buffer = current_fault_entry_rd.parm2;
return ESUCCESS;
}
break;
case RNPOP_WRITE:
case 0x0503:
i = *(int32_t*)buffer;
i &= (1<<flog_width)-1;
if (i2cee_load( flog_base + (i * sizeof(fault_entry_t)), &current_fault_entry_rd, sizeof(fault_entry_t) ) < 0){
flog_current_rd = -1;
} else {
flog_current_rd = i;
};
return ESUCCESS;
break;
};
return -1;
}