Ver. 0.1.0. Storing data into flash.

This commit is contained in:
eddyem 2019-09-20 12:46:08 +03:00
parent 7be1737383
commit ffef1590fc
11 changed files with 170 additions and 117 deletions

View File

@ -9,7 +9,7 @@ MCU ?= F103x8
DENSITY ?= MD
# change this linking script depending on particular MCU model,
LDSCRIPT ?= stm32F103xB.ld
DEFS = -DVERSION=\"0.0.2\"
DEFS = -DVERSION=\"0.1.0\"
# debug
#DEFS += -DEBUG
# proxy GPS output over USART1

Binary file not shown.

View File

@ -45,8 +45,8 @@
#include <string.h> // memcpy
// max amount of records stored: Config & Logs
static int maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
static int maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
int maxCnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
int maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
// common structure for all datatypes stored
/*typedef struct {
@ -63,7 +63,8 @@ static int maxLnum = FLASH_BLOCK_SIZE / sizeof(user_conf);
,.ADC_min = ADC_MIN_VAL \
,.ADC_max = ADC_MAX_VAL \
,.USART_speed = USART1_DEFAULT_SPEED \
,.strendRN = 0 \
,.defflags = 0 \
,.NLfreeWarn = 100 \
}
// change to placement
@ -131,9 +132,6 @@ void flashstorage_init(){
memcpy(&the_conf, &Flash_Data[currentconfidx], sizeof(user_conf));
}
currentlogidx = binarySearch(0, maxLnum-2, (uint8_t*)logsstart, sizeof(event_log));
SEND("\ncurrentconfidx="); printu(1, currentconfidx);
SEND("\ncurrentlogidx="); printu(1, currentlogidx);
newline();
}
// store new configuration
@ -144,28 +142,42 @@ int store_userconf(){
if(currentconfidx > maxCnum - 3){ // there's no more place
currentconfidx = 0;
DBG("Need to erase flash!");
if(erase_flash(Flash_Data, &__varsend)) return 1;
if(erase_flash(Flash_Data, logsstart)) return 1;
}else ++currentconfidx; // take next data position (0 - within first run after firmware flashing)
SEND("store_userconf\n");
SEND("\ncurrentconfidx="); printu(1, currentconfidx);
newline();
return write2flash(&Flash_Data[currentconfidx], &the_conf, sizeof(the_conf));
}
/**
* @brief store_log - save log record L into flash memory
* @param L - event log
* @param L - event log (or NULL to delete flash)
* @return 0 if all OK
*/
int store_log(event_log *L){
if(!L){
currentlogidx = -1;
return erase_flash(logsstart, NULL);
}
if(currentlogidx > maxLnum - 3){ // there's no more place
currentlogidx = 0;
/*currentlogidx = 0;
DBG("Need to erase flash!");
if(erase_flash(logsstart, NULL)) return 1;
if(erase_flash(logsstart, NULL)) return 1;*/
// prevent automatic logs erasing!
USB_send("\n\nERROR!\nCan't save logs: delete old manually!!!\n");
return 1;
}else ++currentlogidx; // take next data position (0 - within first run after firmware flashing)
SEND("sore_log\n");
SEND("\ncurrentlogidx="); printu(1, currentlogidx);
newline();
// put warning if there's little space
if(currentlogidx + the_conf.NLfreeWarn > maxLnum - 3){
uint32_t nfree = maxLnum - 2 - currentlogidx;
USB_send("\n\nWARNING!\nCan store only ");
USB_send(u2str(nfree));
USB_send(" logs!\n\n");
}
/*
USB_send("Stored #"); USB_send(u2str(currentlogidx));
USB_send(", max="); USB_send(u2str(maxLnum));
USB_send(", warn="); USB_send(u2str(the_conf.NLfreeWarn));
USB_send("\n");
*/
return write2flash(&logsstart[currentlogidx], L, sizeof(event_log));
}
@ -177,11 +189,14 @@ newline();
*/
int dump_log(int start, int Nlogs){
if(currentlogidx < 0) return 1;
if(start < 0) start += currentlogidx;
if(start < 0){
start += currentlogidx + 1;
if(start < 0) start = 0;
}
if(start > currentlogidx) return 1;
int nlast;
if(Nlogs > 0){
nlast = start + Nlogs;
nlast = start + Nlogs - 1;
if(nlast > currentlogidx) nlast = currentlogidx;
}else nlast = currentlogidx;
++nlast;

View File

@ -36,10 +36,10 @@
*/
typedef struct __attribute__((packed, aligned(4))){
uint16_t userconf_sz; // "magick number"
uint16_t NLfreeWarn; // warn user when there's less free log records than NLfreeWarn
int16_t ADC_min; // min&max values of ADC (shot when ADval > ADC_min && < ADC_max)
int16_t ADC_max; // !!! BOTH ARE SIGNED! so you can include 0 & 4096
uint8_t trigstate; // level in `triggered` state
uint8_t strendRN; // strings ends with "\r\n" instead of normal "\n"
uint8_t defflags; // default flags
uint32_t dist_min; // minimal distance for LIDAR
uint32_t dist_max; // maximal -//-
@ -48,7 +48,10 @@ typedef struct __attribute__((packed, aligned(4))){
} user_conf;
// values for user_conf.defflags:
// save events in flash
#define FLAG_SAVE_EVENTS (1 << 0)
// strings ends with "\r\n" instead of normal "\n"
#define FLAG_STRENDRN (1 << 1)
/*
* struct to save events logs
@ -64,7 +67,10 @@ typedef struct __attribute__((packed, aligned(4))){
extern user_conf the_conf;
extern const user_conf *Flash_Data;
extern const event_log *logsstart;
extern uint32_t _varslen, __varsstart, __varsend, __logsstart;
extern int maxCnum, maxLnum;
// data from ld-file
extern uint32_t _varslen, __varsstart, __logsstart;
void flashstorage_init();
int store_userconf();

View File

@ -183,7 +183,7 @@ static char *get_USB(){
USB_send(curptr); // echo
//USB_send("ENDOINPUT\n");
//if(x == 1 && *curptr < 32){USB_send("\n"); USB_send(u2str(*curptr)); USB_send("\n");}
if(curptr[x-1] == '\n' || curptr[x-1] == '\r'){
if(curptr[x-1] == '\n'){ // || curptr[x-1] == '\r'){
curptr = tmpbuf;
rest = USBBUF;
// omit empty lines

View File

@ -78,7 +78,18 @@ SECTIONS {
.myvars :
{
. = ALIGN(1024);
KEEP(*(.myvars))
__varsstart = ABSOLUTE(.);
KEEP(*(.myvars));
. = . + 2000;
. = ALIGN(1024);
__varsend = ABSOLUTE(.);
} > rom
.logs :
{
. = ALIGN(1024);
__logsstart = ABSOLUTE(.);
KEEP(*(.logs))
} > rom
_ldata = LOADADDR(.data);
@ -95,3 +106,4 @@ SECTIONS {
}
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));
PROVIDE(_varslen = __varsend - __varsstart);

View File

@ -86,12 +86,14 @@ static void showuserconf(){
USB_send("}");
USB_send("\nUSART1SPD="); sendu(the_conf.USART_speed);
USB_send("\nSTREND=");
if(the_conf.strendRN) USB_send("RN");
if(the_conf.defflags & FLAG_STRENDRN) USB_send("RN");
else USB_send("N");
uint8_t f = the_conf.defflags;
USB_send("\nSAVE_EVENTS=");
if(f & FLAG_SAVE_EVENTS) USB_send("1");
else USB_send("0");
USB_send("\nNFREE=");
sendu(the_conf.NLfreeWarn);
USB_send("\n");
}
@ -114,25 +116,27 @@ int parse_USBCMD(char *cmd){
CMD_ADCMIN " - min -//- (triggered when ADval>min & <max)\n"
CMD_GETADCVAL " - get ADC value\n"
CMD_BUZZER "S - turn buzzer ON/OFF\n"
CMD_DELLOGS " - delete logs from flash memory\n"
CMD_DISTMIN " - min distance threshold (cm)\n"
CMD_DISTMAX " - max distance threshold (cm)\n"
CMD_DUMP " - dump stored events\n"
CMD_DUMP "N - dump 20 last stored events (no x), all (x<1) or x\n"
CMD_FLASH " - FLASH info\n"
CMD_GPSRESTART " - send Full Cold Restart to GPS\n"
CMD_GPSSTAT " - get GPS status\n"
CMD_GPSSTR " - current GPS data string\n"
CMD_LEDS "S - turn leds on/off (1/0)\n"
CMD_GETMCUTEMP " - MCU temperature\n"
CMD_SHOWCONF " - show current configuration\n"
CMD_NFREE " - warn when free logs space less than this number (0 - not warn)"
CMD_PRINTTIME " - print time\n"
CMD_RESET " - reset MCU\n"
CMD_SAVEEVTS "x - save/don't save (1/0) trigger events into flash\n"
CMD_SAVEEVTS "S - save/don't save (1/0) trigger events into flash\n"
CMD_SHOWCONF " - show current configuration\n"
CMD_STORECONF " - store new configuration in flash\n"
CMD_STREND "x - string ends with \\n (x=n) or \\r\\n (x=r)\n"
CMD_STREND "C - string ends with \\n (C=n) or \\r\\n (C=r)\n"
CMD_TRIGLVL "NS - working trigger N level S\n"
CMD_TRGPAUSE "NP - pause (P, ms) after trigger N shots\n"
CMD_TRGTIME "N - show last trigger N time\n"
CMD_USARTSPD "V - set USART1 speed to V\n"
CMD_USARTSPD "N - set USART1 speed to N\n"
CMD_GETVDD " - Vdd value\n"
);
}else if(CMP(cmd, CMD_PRINTTIME) == 0){
@ -168,21 +172,7 @@ int parse_USBCMD(char *cmd){
}
}else if(CMP(cmd, CMD_GPSSTR) == 0){ // show GPS status string
showGPSstr = 1;
}/*
else if(CMP(cmd, CMD_PULLUP) == 0){
DBG("Pullups");
cmd += sizeof(CMD_PULLUP) - 1;
uint8_t Nt = *cmd++ - '0';
if(Nt > TRIGGERS_AMOUNT - 1) goto bad_number;
uint8_t state = *cmd -'0';
if(state > 1) goto bad_number;
uint8_t oldval = the_conf.trig_pullups;
if(!state) the_conf.trig_pullups = oldval & ~(1<<Nt);
else the_conf.trig_pullups = oldval | (1<<Nt);
if(oldval != the_conf.trig_pullups) conf_modified = 1;
succeed = 1;
} */
else if(CMP(cmd, CMD_TRIGLVL) == 0){
}else if(CMP(cmd, CMD_TRIGLVL) == 0){
DBG("Trig levels");
cmd += sizeof(CMD_TRIGLVL) - 1;
uint8_t Nt = *cmd++ - '0';
@ -315,8 +305,8 @@ int parse_USBCMD(char *cmd){
}else if(CMP(cmd, CMD_STREND) == 0){
char c = cmd[sizeof(CMD_STREND) - 1];
succeed = 1;
if(c == 'n' || c == 'N') the_conf.strendRN = 0;
else if(c == 'r' || c == 'R') the_conf.strendRN = 1;
if(c == 'n' || c == 'N') the_conf.defflags &= ~FLAG_STRENDRN;
else if(c == 'r' || c == 'R') the_conf.defflags |= FLAG_STRENDRN;
else{
succeed = 0;
USB_send("Bad letter, should be 'n' or 'r'\n");
@ -325,24 +315,39 @@ int parse_USBCMD(char *cmd){
USB_send("FLASHSIZE=");
sendu(FLASH_SIZE);
USB_send("kB\nFLASH_BASE=");
sendu(FLASH_BASE);
USB_send(u2hex(FLASH_BASE));
USB_send("\nFlash_Data=");
sendu((uint32_t)Flash_Data);
USB_send(u2hex((uint32_t)Flash_Data));
USB_send("\nvarslen=");
sendu((uint32_t)&_varslen);
USB_send("\nvarsend=");
sendu((uint32_t)&__varsend);
USB_send("\nvarsstart=");
sendu((uint32_t)&__varsstart);
USB_send("\nCONFsize=");
sendu(sizeof(user_conf));
USB_send("\nNconf_records=");
sendu(maxCnum - 1);
USB_send("\nlogsstart=");
sendu((uint32_t)logsstart);
USB_send(u2hex((uint32_t)logsstart));
USB_send("\nLOGsize=");
sendu(sizeof(event_log));
USB_send("\nNlogs_records=");
sendu(maxLnum - 1);
USB_send("\n");
}else if(CMP(cmd, CMD_SAVEEVTS) == 0){
if('0' == cmd[sizeof(CMD_SAVEEVTS) - 1]) the_conf.defflags &= ~FLAG_SAVE_EVENTS;
else the_conf.defflags |= FLAG_SAVE_EVENTS;
succeed = 1;
}else if(CMP(cmd, CMD_DUMP) == 0){
if(dump_log(0, -1)) USB_send("Event log empty!\n");
if(getnum(cmd+sizeof(CMD_DUMP)-1, &N)) N = -20; // default - without N
else N = -N;
if(N > 0) N = 0;
if(dump_log(N, -1)) USB_send("Event log empty!\n");
}else if(CMP(cmd, CMD_NFREE) == 0){
GETNUM(CMD_NFREE);
if(N < 0 || N > 0xffff) goto bad_number;
the_conf.NLfreeWarn = (uint16_t)N;
succeed = 1;
}else if(CMP(cmd, CMD_DELLOGS) == 0){
if(store_log(NULL)) USB_send("Error during erasing flash\n");
else USB_send("All logs erased\n");
}else return 1;
/*else if(CMP(cmd, CMD_) == 0){
;
@ -433,3 +438,70 @@ char *strcp(char* dst, const char *src){
while((*dst++ = *src++));
return dst - 1;
}
// read `buf` and get first integer `N` in it
// @return 0 if all OK or 1 if there's not a number; omit spaces and '='
int getnum(const char *buf, int32_t *N){
char c;
int positive = -1;
int32_t val = 0;
while((c = *buf++)){
if(c == '\t' || c == ' ' || c == '='){
if(positive < 0) continue; // beginning spaces
else break; // spaces after number
}
if(c == '-'){
if(positive < 0){
positive = 0;
continue;
}else break; // there already was `-` or number
}
if(c < '0' || c > '9') break;
if(positive < 0) positive = 1;
val = val * 10 + (int32_t)(c - '0');
}
if(positive != -1){
if(positive == 0){
if(val == 0) return 1; // single '-'
val = -val;
}
*N = val;
}else return 1;
return 0;
}
static char strbuf[11];
// return string buffer (strbuf) with val
char *u2str(uint32_t val){
char *bufptr = &strbuf[10];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
*(--bufptr) = val % 10 + '0';
val /= 10;
}
}
return bufptr;
}
// return strbuf filled with hex
char *u2hex(uint32_t val){
char *bufptr = strbuf;
*bufptr++ = '0';
*bufptr++ = 'x';
uint8_t *ptr = (uint8_t*)&val + 3;
int i, j;
IWDG->KR = IWDG_REFRESH;
for(i = 0; i < 4; ++i, --ptr){
for(j = 1; j > -1; --j){
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) *bufptr++ = half + '0';
else *bufptr++ = half - 10 + 'a';
}
}
*bufptr = 0;
return strbuf;
}

View File

@ -47,11 +47,17 @@
#define CMD_RESET "reset"
#define CMD_STREND "strend"
#define CMD_FLASH "flash"
#define CMD_SAVEEVTS "saveevt"
#define CMD_SAVEEVTS "se"
#define CMD_DUMP "dump"
#define CMD_NFREE "nfree"
#define CMD_DELLOGS "deletelogs"
extern uint8_t showGPSstr;
int getnum(const char *buf, int32_t *N);
char *u2str(uint32_t val);
char *u2hex(uint32_t val);
int strln(const char *s);
char *strcp(char* dst, const char *src);
int cmpstr(const char *s1, const char *s2, int n);

View File

@ -19,8 +19,9 @@
#include "stm32f1.h"
#include "flash.h"
#include "usart.h"
#include "lidar.h"
#include "str.h"
#include "usart.h"
extern volatile uint32_t Tms;
static volatile int idatalen[4][2] = {0}; // received data line length (including '\n')
@ -252,22 +253,6 @@ void usart3_isr(){
}
}
// return string buffer with val
char *u2str(uint32_t val){
static char buf[11];
char *bufptr = &buf[10];
*bufptr = 0;
if(!val){
*(--bufptr) = '0';
}else{
while(val){
*(--bufptr) = val % 10 + '0';
val /= 10;
}
}
return bufptr;
}
// print 32bit unsigned int
void printu(int n, uint32_t val){
usart_send(n, u2str(val));
@ -275,17 +260,7 @@ void printu(int n, uint32_t val){
// print 32bit unsigned int as hex
void printuhex(int n, uint32_t val){
usart_send(n, "0x");
uint8_t *ptr = (uint8_t*)&val + 3;
int i, j;
IWDG->KR = IWDG_REFRESH;
for(i = 0; i < 4; ++i, --ptr){
for(j = 1; j > -1; --j){
register uint8_t half = (*ptr >> (4*j)) & 0x0f;
if(half < 10) usart_putchar(n, half + '0');
else usart_putchar(n, half - 10 + 'a');
}
}
usart_send(n, u2hex(val));
}
#ifdef EBUG
@ -326,34 +301,3 @@ void dma1_channel2_isr(){ // USART3
txrdy[3] = 1;
}
}
// read `buf` and get first integer `N` in it
// @return 0 if all OK or 1 if there's not a number; omit spaces and '='
int getnum(const char *buf, int32_t *N){
char c;
int positive = -1;
int32_t val = 0;
while((c = *buf++)){
if(c == '\t' || c == ' ' || c == '='){
if(positive < 0) continue; // beginning spaces
else break; // spaces after number
}
if(c == '-'){
if(positive < 0){
positive = 0;
continue;
}else break; // there already was `-` or number
}
if(c < '0' || c > '9') break;
if(positive < 0) positive = 1;
val = val * 10 + (int32_t)(c - '0');
}
if(positive != -1){
if(positive == 0){
if(val == 0) return 1; // single '-'
val = -val;
}
*N = val;
}else return 1;
return 0;
}

View File

@ -55,10 +55,8 @@ void usarts_setup();
int usart_getline(int n, char **line);
void usart_send(int n, const char *str);
void usart_putchar(int n, char ch);
char *u2str(uint32_t val);
void printu(int n, uint32_t val);
void printuhex(int n, uint32_t val);
int getnum(const char *buf, int32_t *N);
#if defined EBUG || defined USART1PROXY
void newline();

View File

@ -115,7 +115,7 @@ void USB_send(const char *buf){
uint16_t proc = 0, s = (l > USB_TXBUFSZ - 1) ? USB_TXBUFSZ - 1: l;
for(int i = 0; i < s; ++i, ++proc){
char c = buf[ctr+proc];
if(c == '\n' && the_conf.strendRN){ // add '\r' before '\n'
if(c == '\n' && the_conf.defflags & FLAG_STRENDRN){ // add '\r' before '\n'
tmpbuf[i++] = '\r';
if(i == s) ++s;
}