persistentCounter.c etc.: made the persistent counter more versatile, it

is not limited to hard reset counts anymore
This commit is contained in:
Christian Kroll 2014-09-07 21:06:25 +02:00
parent 967ab9a05e
commit 7d0022a22d
5 changed files with 71 additions and 61 deletions

View File

@ -94,7 +94,8 @@ void display_loop(){
#ifdef RANDOM_SUPPORT #ifdef RANDOM_SUPPORT
{ {
char a[28]; char a[28];
sprintf(a,"</# counter == %lu ", (unsigned long) percnt_get()); sprintf(a,"</# counter == %lu ",
(unsigned long)percnt_get(&g_reset_counter, &g_reset_counter_idx));
scrolltext(a); scrolltext(a);
} }
#endif #endif

View File

@ -32,8 +32,8 @@ int main (void){
clear_screen(0); clear_screen(0);
#ifdef RANDOM_SUPPORT #ifdef RANDOM_SUPPORT
srandom32(percnt_get()); srandom32(percnt_get(&g_reset_counter, &g_reset_counter_idx));
percnt_inc(); percnt_inc(&g_reset_counter, &g_reset_counter_idx);
#endif #endif
#ifdef RFM12_SUPPORT #ifdef RFM12_SUPPORT

View File

@ -9,103 +9,105 @@
#include "../compat/interrupt.h" /* cli() & sei() */ #include "../compat/interrupt.h" /* cli() & sei() */
#include "../compat/eeprom.h" #include "../compat/eeprom.h"
#include "../config.h" #include "../config.h"
#include "persistentCounter.h"
#ifdef ERROR_HANDLING #ifdef ERROR_HANDLING
#include "error-handling.h" # include "error-handling.h"
#define PERSISTENT_COUNTER_OVERFLOW (void*)0, 2,4,1 # define PERSISTENT_COUNTER_OVERFLOW (void*)0, 2,4,1
#define PERSISTENT_COUNTER_WRITER_ERROR (void*)0, 2,4,2 # define PERSISTENT_COUNTER_WRITER_ERROR (void*)0, 2,4,2
#endif #endif
#define RING_SIZE 168 uint8_t g_reset_counter_idx = 0xff;
percnt_t EEMEM g_reset_counter;
uint8_t ring_idx = 0xff;
uint16_t EEMEM B08_23;
uint8_t EEMEM B0_7[RING_SIZE];
#ifdef INIT_EEPROM #ifdef INIT_EEPROM
void init_buffer(void){ void init_buffer(percnt_t *percnt, uint8_t *ring_index) {
uint8_t i; uint8_t i;
eeprom_busy_wait(); eeprom_busy_wait();
eeprom_write_word(&B08_23, 0x0000); eeprom_write_word(&(percnt->B08_23), 0x0000);
for(i=0; i<RING_SIZE; ++i){ for (i = 0; i < RING_SIZE; ++i) {
eeprom_busy_wait(); eeprom_busy_wait();
eeprom_write_byte(&(B0_7[i]), 0x00); eeprom_write_byte(&(percnt->B0_7[i]), 0x00);
} }
} }
#endif #endif
void percnt_init(void){ void percnt_init(percnt_t *percnt, uint8_t *ring_index) {
uint8_t i; uint8_t i;
uint8_t maxidx=0; uint8_t maxidx = 0;
uint8_t t,max=eeprom_read_byte(&(B0_7[0])); uint8_t t, max = eeprom_read_byte(&(percnt->B0_7[0]));
#ifdef INIT_EEPROM #ifdef INIT_EEPROM
if (eeprom_read_word(&B08_23)==0xFFFF){ /* test if the 2 MSB == 0xFFFF*/ /* test if the 2 MSB == 0xFFFF */
if (eeprom_read_word((uint16_t*)&(B0_7[0]))==0xFFFF) /* test the first to bytes of ringbuffer*/ if (eeprom_read_word(&(percnt->B08_23)) == 0xFFFF) {
init_buffer(); /* test the first two bytes of ringbuffer */
} if (eeprom_read_word((uint16_t*) &(percnt->B0_7[0])) == 0xFFFF)
#endif init_buffer(percnt, ring_index);
for(i=0; i<RING_SIZE; ++i){ /* this might be speed up, but such optimisation could lead to timing attacks */ }
#endif
/* might be faster, but such optimizations are prone to timing attacks */
for (i = 0; i < RING_SIZE; ++i) {
eeprom_busy_wait(); eeprom_busy_wait();
t=eeprom_read_byte(&(B0_7[i])); t = eeprom_read_byte(&(percnt->B0_7[i]));
if(t==max+1){ if (t == max + 1) {
max=t; max = t;
maxidx=i; maxidx = i;
} }
} }
ring_idx = (maxidx==RING_SIZE)?0:maxidx; *ring_index = (maxidx == RING_SIZE) ? 0 : maxidx;
} }
uint32_t percnt_get(void){ uint32_t percnt_get(percnt_t *percnt, uint8_t *ring_index) {
uint32_t ret=0; uint32_t ret = 0;
if(ring_idx==0xff) if (*ring_index == 0xff)
percnt_init(); percnt_init(percnt, ring_index);
cli(); cli();
eeprom_busy_wait(); eeprom_busy_wait();
ret=eeprom_read_word(&B08_23)<<8; ret = eeprom_read_word(&(percnt->B08_23)) << 8;
eeprom_busy_wait(); eeprom_busy_wait();
ret |= eeprom_read_byte(&(B0_7[ring_idx])); ret |= eeprom_read_byte(&(percnt->B0_7[*ring_index]));
sei(); sei();
return ret; return ret;
} }
void percnt_inc(void){ void percnt_inc(percnt_t *percnt, uint8_t *ring_index) {
/* we must make this resistant agaist power off while this is running ... */ /* we must make this resistant agaist power off while this is running ... */
uint32_t u; uint32_t u;
if(ring_idx==0xff)
percnt_init();
u = percnt_get(); if (*ring_index == 0xff)
percnt_init(percnt, ring_index);
u = percnt_get(percnt, ring_index);
cli(); cli();
/* it's important to write msb first! */ /* it's important to write msb first! */
if((u&0x000000ff) == 0xff){ if ((u & 0x000000ff) == 0xff) {
if((u&0x0000ffff) == 0xffff){ if ((u & 0x0000ffff) == 0xffff) {
if((u&0x00ffffff) == 0xffffff){ if ((u & 0x00ffffff) == 0xffffff) {
/* we can turn the lights off now. it's time to die */ /* we can turn the lights off now. it's time to die */
#ifdef ERROR_HANDLING #ifdef ERROR_HANDLING
error(PERSISTENT_COUNTER_OVERFLOW); error(PERSISTENT_COUNTER_OVERFLOW);
#endif #endif
} }
eeprom_busy_wait(); eeprom_busy_wait();
eeprom_write_byte(&(((uint8_t*)&B08_23)[1]),((u+1)>>16)&0xff); eeprom_write_byte(&(((uint8_t*) &(percnt->B08_23))[1]),
((u + 1) >> 16) & 0xff);
} }
eeprom_busy_wait(); eeprom_busy_wait();
eeprom_write_byte(&(((uint8_t*)&B08_23)[0]),((u+1)>>8)&0xff); eeprom_write_byte(&(((uint8_t*) &(percnt->B08_23))[0]),
((u + 1) >> 8) & 0xff);
} }
/* set least significant byte (in ringbuffer) */ /* set least significant byte (in ringbuffer) */
ring_idx = (ring_idx+1)%RING_SIZE; *ring_index = (*ring_index + 1) % RING_SIZE;
eeprom_busy_wait(); eeprom_busy_wait();
eeprom_write_byte(&(B0_7[ring_idx]),(u+1)&0xff); eeprom_write_byte(&(percnt->B0_7[*ring_index]), (u + 1) & 0xff);
eeprom_busy_wait(); eeprom_busy_wait();
if(u+1 != percnt_get()){ if (u + 1 != percnt_get(percnt, ring_index)) {
#ifdef ERROR_HANDLING #ifdef ERROR_HANDLING
error(PERSISTENT_COUNTER_WRITER_ERROR); error(PERSISTENT_COUNTER_WRITER_ERROR);
#endif #endif
} }
sei(); sei();
} }

View File

@ -9,15 +9,22 @@
#ifndef PERSISTENTCOUNTER_H_ #ifndef PERSISTENTCOUNTER_H_
#define PERSISTENTCOUNTER_H_ #define PERSISTENTCOUNTER_H_
#include <stdint.h> #include <stdint.h>
#include "../compat/eeprom.h"
#define PERSISTENT_COUNTER_BITS 24 #define PERSISTENT_COUNTER_BITS 24
#define RING_SIZE 168
void percnt_init(void); typedef struct percnt_s {
uint32_t percnt_get(void); uint16_t B08_23;
void percnt_inc(void); uint8_t B0_7[RING_SIZE];
} percnt_t;
extern uint8_t g_reset_counter_idx;
extern percnt_t g_reset_counter EEMEM;
void percnt_init(percnt_t *percnt, uint8_t *ring_index);
uint32_t percnt_get(percnt_t *percnt, uint8_t *ring_index);
void percnt_inc(percnt_t *percnt, uint8_t *ring_index);
#endif /*PERSISTENTCOUNTER_H_*/ #endif /*PERSISTENTCOUNTER_H_*/

View File

@ -227,7 +227,7 @@ static void uartcmd_read_mode(void) {
/** /**
* Perform a MCU reset by triggering the watchdog. * Perform a MCU reset by triggering the watchdog.
*/ */
static void uartcmd_reset_borg() { static void uartcmd_reset_borg(void) {
timer0_off(); timer0_off();
} }