diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ao.h | 11 | ||||
| -rw-r--r-- | src/ao_config.c | 20 | ||||
| -rw-r--r-- | src/ao_ee.c | 12 | ||||
| -rw-r--r-- | src/ao_flash.c | 12 | ||||
| -rw-r--r-- | src/ao_log.c | 231 | 
5 files changed, 265 insertions, 21 deletions
| @@ -443,6 +443,8 @@ extern __xdata uint32_t	ao_storage_block;  /* Byte offset of config block. Will be ao_storage_block bytes long */  extern __xdata uint32_t	ao_storage_config; +#define AO_STORAGE_ERASE_LOG	(ao_storage_config + AO_CONFIG_MAX_SIZE) +  /* Initialize above values. Can only be called once the OS is running */  void  ao_storage_setup(void); @@ -459,6 +461,10 @@ ao_storage_write(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant;  uint8_t  ao_storage_read(uint32_t pos, __xdata void *buf, uint16_t len) __reentrant; +/* Erase a block of storage. This always clears ao_storage_block bytes */ +uint8_t +ao_storage_erase(uint32_t pos); +  /* Initialize the storage code */  void  ao_storage_init(void); @@ -993,10 +999,15 @@ struct ao_config {  extern __xdata struct ao_config ao_config; +#define AO_CONFIG_MAX_SIZE	128 +  void  ao_config_get(void);  void +ao_config_put(void); + +void  ao_config_init(void);  /* diff --git a/src/ao_config.c b/src/ao_config.c index 2153b841..2673e472 100644 --- a/src/ao_config.c +++ b/src/ao_config.c @@ -36,6 +36,14 @@ _ao_config_put(void)  	ao_storage_write(ao_storage_config, &ao_config, sizeof (ao_config));  	ao_storage_flush();  } + +void +ao_config_put(void) +{ +	ao_mutex_get(&ao_config_mutex); +	_ao_config_put(); +	ao_mutex_put(&ao_config_mutex); +}  #endif  static void @@ -288,13 +296,13 @@ struct ao_config_var {  	const char	*help;  }; -void +static void  ao_config_help(void) __reentrant; -void +static void  ao_config_show(void) __reentrant; -void +static void  ao_config_write(void) __reentrant;  __code struct ao_config_var ao_config_vars[] = { @@ -348,7 +356,7 @@ ao_config_set(void)  		ao_cmd_status = ao_cmd_syntax_error;  } -void +static void  ao_config_help(void) __reentrant  {  	uint8_t cmd; @@ -356,7 +364,7 @@ ao_config_help(void) __reentrant  		puts (ao_config_vars[cmd].help);  } -void +static void  ao_config_show(void) __reentrant  {  	uint8_t cmd; @@ -368,7 +376,7 @@ ao_config_show(void) __reentrant  }  #if HAS_EEPROM -void +static void  ao_config_write(void) __reentrant  {  	uint8_t saved = 0; diff --git a/src/ao_ee.c b/src/ao_ee.c index 6fe88252..575a7b30 100644 --- a/src/ao_ee.c +++ b/src/ao_ee.c @@ -246,6 +246,18 @@ ao_storage_flush(void) __reentrant  	} ao_mutex_put(&ao_ee_mutex);  } +uint8_t +ao_storage_erase(uint32_t pos) __reentrant +{ +	ao_mutex_get(&ao_ee_mutex); { +		uint16_t block = (uint16_t) (pos >> 8); +		ao_ee_fill(block); +		memset(ao_ee_data, 0xff, EE_BLOCK_SIZE); +		ao_ee_block_dirty = 1; +	} ao_mutex_put(&ao_ee_mutex); +	return 1; +} +  static void  ee_dump(void) __reentrant  { diff --git a/src/ao_flash.c b/src/ao_flash.c index 3a06bae1..bc8b56ad 100644 --- a/src/ao_flash.c +++ b/src/ao_flash.c @@ -322,6 +322,18 @@ ao_storage_flush(void) __reentrant  	} ao_mutex_put(&ao_flash_mutex);  } +uint8_t +ao_storage_erase(uint32_t pos) __reentrant +{ +	ao_mutex_get(&ao_flash_mutex); { +		uint16_t block = (uint16_t) (pos >> ao_flash_block_shift); +		ao_flash_fill(block); +		memset(ao_flash_data, 0xff, ao_flash_block_size); +		ao_flash_block_dirty = 1; +	} ao_mutex_put(&ao_flash_mutex); +	return 1; +} +  static void  flash_dump(void) __reentrant  { diff --git a/src/ao_log.c b/src/ao_log.c index 30acc50a..132512e6 100644 --- a/src/ao_log.c +++ b/src/ao_log.c @@ -61,6 +61,8 @@ ao_log_flush(void)  	ao_storage_flush();  } +static void ao_log_scan(void); +  __xdata struct ao_log_record log;  __xdata uint16_t ao_flight_number; @@ -72,21 +74,6 @@ ao_log_dump_check_data(void)  	return 1;  } -static void -ao_log_scan(void) -{ -	if (!ao_storage_read(0, &log, sizeof (struct ao_log_record))) -		ao_panic(AO_PANIC_LOG); -	if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT) { -		ao_flight_number = log.u.flight.flight + 1; -		if (ao_flight_number == 0) -			ao_flight_number = 1; -	} else { -		ao_flight_number = 1; -	} -	ao_wakeup(&ao_flight_number); -} -  __xdata uint8_t	ao_log_adc_pos;  __xdata enum flight_state ao_log_state; @@ -161,6 +148,160 @@ ao_log(void)  	}  } +/* + * When erasing a flight log, make sure the config block + * has an up-to-date version of the current flight number + */ + +struct ao_log_erase { +	uint8_t	unused; +	uint16_t flight; +}; + +static __xdata struct ao_log_erase erase; + +#define LOG_MAX_ERASE	16 + +static uint32_t +ao_log_erase_pos(uint8_t i) +{ +	return i * sizeof (struct ao_log_erase) + AO_STORAGE_ERASE_LOG; +} + +static void +ao_log_write_erase(uint8_t pos) +{ +	erase.unused = 0x00; +	erase.flight = ao_flight_number; +	ao_storage_write(ao_log_erase_pos(pos),  &erase, sizeof (erase)); +} + +static void +ao_log_read_erase(uint8_t pos) +{ +	ao_storage_read(ao_log_erase_pos(pos), &erase, sizeof (erase)); +} + + +static void +ao_log_erase_mark(void) +{ +	uint8_t				i; + +	for (i = 0; i < LOG_MAX_ERASE; i++) { +		ao_log_read_erase(i); +		if (erase.unused == 0 && erase.flight == ao_flight_number) +			return; +		if (erase.unused == 0xff) { +			ao_log_write_erase(i); +			return; +		} +	} +	ao_config_put(); +} + +static void +ao_log_erase(uint8_t pos) +{ +	ao_config_get(); +	(void) pos; +//	ao_log_current_pos = pos * ao_config.flight_log_max; +//	ao_log_end_pos = ao_log_current_pos + ao_config.flight_log_max; +//	if (ao_log_end_pos > ao_storage_config) +//		return; + +	ao_log_current_pos = 0; +	ao_log_end_pos = ao_storage_config; + +	while (ao_log_current_pos < ao_log_end_pos) { +		ao_storage_erase(ao_log_current_pos); +		ao_log_current_pos += ao_storage_block; +	} +} + +static uint16_t +ao_log_flight(uint8_t slot) +{ +	(void) slot; +	if (!ao_storage_read(0, +			     &log, +			     sizeof (struct ao_log_record))) +		ao_panic(AO_PANIC_LOG); + +	if (ao_log_dump_check_data() && log.type == AO_LOG_FLIGHT) +		return log.u.flight.flight; +	return 0; +} + +static void +ao_log_scan(void) +{ +	uint8_t		log_slot; +	uint8_t		log_avail = 0; +	uint16_t	log_flight; + +	ao_config_get(); + +	ao_flight_number = 0; + +	/* Scan the log space looking for an empty one, and find the biggest flight number */ +	log_slot = 0; +	{ +		log_flight = ao_log_flight(log_slot); +		if (log_flight) { +			if (++log_flight == 0) +				log_flight = 1; +			if (ao_flight_number == 0 || +			    (int16_t) (log_flight - ao_flight_number) > 0) { +				ao_flight_number = log_flight; +			} +		} else +			log_avail |= 1 << log_slot; +	} + +	/* Now look through the log of flight numbers from erase operations and +	 * see if the last one is bigger than what we found above +	 */ +	for (log_slot = LOG_MAX_ERASE; log_slot-- > 0;) { +		ao_log_read_erase(log_slot); +		if (erase.unused == 0) { +			if (ao_flight_number == 0 || +			    (int16_t) (erase.flight - ao_flight_number) > 0) +				ao_flight_number = erase.flight; +			break; +		} +	} +	if (ao_flight_number == 0) +		ao_flight_number = 1; + +	/* With a flight number in hand, find a place to write a new log, +	 * use the target flight number to index the available log slots so +	 * that we write logs to each spot about the same number of times. +	 */ + +	/* If there are no log slots available, then +	 * do not log the next flight +	 */ +	if (!log_avail) { +		ao_log_current_pos = 0; +		ao_log_end_pos = 0; +	} else { +		log_slot = ao_flight_number % log_slot; +		while (!((log_avail & (1 << log_slot)))) { +			if ((1 << log_slot) > log_avail) +				log_slot = 0; +			else +				log_slot++; +		} +//		ao_log_current_pos = log_slot * ao_config.flight_log_max; +//		ao_log_end_pos = ao_log_current_pos + ao_config.flight_log_max; +		ao_log_current_pos = 0; +		ao_log_end_pos = ao_storage_config; +	} + +	ao_wakeup(&ao_flight_number); +} +  void  ao_log_start(void)  { @@ -179,6 +320,64 @@ ao_log_stop(void)  static __xdata struct ao_task ao_log_task;  void +ao_log_list(void) __reentrant +{ +	uint8_t	slot; +	uint16_t flight; + +	slot = 0; +	{ +		flight = ao_log_flight(slot); +		if (flight) +			printf ("Flight %d\n", flight); +	} +} + +void +ao_log_delete(void) __reentrant +{ +	uint8_t slot; +	ao_cmd_decimal(); +	if (ao_cmd_status != ao_cmd_success) +		return; +	slot = 0; +	/* Look for the flight log matching the requested flight */ +	{ +		if (ao_log_flight(slot) == ao_cmd_lex_i) { +			ao_log_current_pos = 0; +			ao_log_end_pos = ao_storage_config; +			while (ao_log_current_pos < ao_log_end_pos) { +				/* +				 * Check to see if we've reached the end of +				 * the used memory to avoid re-erasing the same +				 * memory over and over again +				 */ +				if (ao_storage_read(ao_log_current_pos, +						    &log, +						    sizeof (struct ao_log_record))) { +					for (slot = 0; slot < sizeof (struct ao_log_record); slot++) +						if (((uint8_t *) &log)[slot] != 0xff) +							break; +					if (slot == sizeof (struct ao_log_record)) +						break; +				} +				ao_storage_erase(ao_log_current_pos); +				ao_log_current_pos += ao_storage_block; +			} +			puts("Erased\n"); +			return; +		} +	} +	printf("No such flight: %d\n", ao_cmd_lex_i); +} + +__code struct ao_cmds ao_log_cmds[] = { +	{ 'l',	ao_log_list,	"l                                  List stored flight logs" }, +	{ 'd',	ao_log_delete,	"d <flight-number>                  Delete stored flight" }, +	{ 0,	ao_log_delete,	NULL }, +}; + +void  ao_log_init(void)  {  	ao_log_running = 0; @@ -186,6 +385,8 @@ ao_log_init(void)  	/* For now, just log the flight starting at the begining of eeprom */  	ao_log_state = ao_flight_invalid; +	ao_cmd_register(&ao_log_cmds[0]); +  	/* Create a task to log events to eeprom */  	ao_add_task(&ao_log_task, ao_log, "log");  } | 
