Hur löser man problemet med olika databasversioner vid uppgr

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45176
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av TomasL »

Eller om man vill ha en ny variabel tillsammans med de gamla som
hör till samma grupp av variabler...
Det är just där problemet ligger.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43152
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av sodjan »

Det är ju två saker, dels om de ska stå tillsammans i källkoden (loopup tabellen,
hanterbart men inte snyggt), dels om man även vill att de ska ligga tillsammans
i minnet (svårare eftersom efterföljande variabler kommer att byta adress...).
Användarvisningsbild
Krille Krokodil
Inlägg: 4062
Blev medlem: 9 december 2005, 22:33:11
Ort: Helsingborg

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av Krille Krokodil »

Någon typ av revisions-skript som gör som scannar C-filen med variabeldeklarationer och lägger ändringar
sist i minnet... Så länge minnet räcker kör man "minor" revisions som är bakåtkompatibla och
när det tar slut får det bli en "major" där alla system måste uppgraderas.
ie
EF Sponsor
Inlägg: 1271
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av ie »

Om datat är statiskt, dvs fasta värden i flash som du läser in till programmet vid behov, så kan du hantera det externt.

Du håller reda på alla variabler och dess värden i t ex Excel. (En kolumn kan vara versionsnummer.) Sen låter du ett skript generera C-kod åt dig. Skriptet kan då ta höjd för versionsnumret, och endast ta med de fält som behövs för en given version.

/Ingvar
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45176
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av TomasL »

Det löser knappast problemet.
Värdena är statisk, och anpassas efter ett enskilt projekt av användaren.
Så jag har inte en susning om vilka värden som är ändrade eller inte.
Totalt rör det sig om runt 3,5k 16-bitars värden, dvs strukturen är ca 7kB stor.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av Mr Andersson »

Varför måste du lägga in nya fält mitt i? Är det bara för att det ska se snyggt ut i källkoden? Processorn bryr sig nog inte så mycket om vilken adress fälten har.

Om uppgradering går att göra från "passivt" minne (sd-kort, usb-minne, etc):
Enklast är nog att ha en versionsbyte först i struct:en (alt. på en adress som inte ändras mellan programversioner). Om eeprom-versionen är lägre än vad programmet förväntar sig fråga användaren om värden för de nya fälten (eller fyll i default-värden) och lägg till i slutet, och uppdatera versionsnumret.

Om uppgradering bara görs från en "smart" enhet, t.ex. dator, telefon, whatever via usb/wifi/nånting annat:
Tanka över eepromet till flash-programvaran och gör de ändringar som behövs och skriv tillbaka. Här är det mycket enklare att flytta om och lägga in nya saker i mitten då du inte har samma resursbegränsningar.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45176
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av TomasL »

Därför att man i vissa lägen vill utöka strukturer, vilka kan ligga mitt i.
Till exempel, jag har en struktur som innehåller ett 20 tal olika digitala utgångsfunktioner, dessa funktioner kan jag koppla till ett antal fysiska digitala utgångar.
Sedan visar det sig att jag behöver ytterligare en eller två digitala utgångsfunktioner (kan vara önskemål från en kund (eller en säljare) att vi skall implementera en viss funktion), då behöver strukturen uppdateras med denna nya funktion, eftersom de ligger i samma struktur, så sparas de per natur sekventiellt i minne, och följaktligen även i flashminnet, vilket då får till följd att data från den tidigare versionen hamnar i osynk, så alla gamla data måste matas in från scratch.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av Mr Andersson »

Okej. Det har ju hjälpt om du skrivit att det gällde flera strukturer istället för en.
"strukturen är ca 7kB stor"

Hur mycket ram finns det? Ryms det att läsa in all flash-data i ram och sen skriva tillbaks en uppdaterad version eller måste det ske i flera steg?
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 45176
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av TomasL »

Ram räcker till och blir över, har väl 128kB ram i den aktuella processorn.
Ja, det är flera understrukturer i databasen.
Vissa av dem har även strukturer i flera nivåer
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av johano »

TomasL skrev:Ram räcker till och blir över, har väl 128kB ram i den aktuella processorn.
Ja, det är flera understrukturer i databasen.
Vissa av dem har även strukturer i flera nivåer
Men är det inte bara att selektera ut de kolumner du är intresserad av då??
typ "select a,b,d from settings" för program 1 och "select c,e,f from settings" för program 2 ?
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43152
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av sodjan »

Det finns ingen "databasmotor" som kan tolka och exekvera de där kommandona.
Det var det jag sa från början, om det hade handlat om en "riktig" databas så hade
det inte varit något problem. Här handlar det "bara" om vanlig versionshantering.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av Mr Andersson »

TomasL skrev:Ram räcker till och blir över, har väl 128kB ram i den aktuella processorn.
Ja, det är flera understrukturer i databasen.
Vissa av dem har även strukturer i flera nivåer
Okej finns det så mycket då är det inga större problem.
Kör på automatisk kodgenerering för att skapa en uppgraderingsfunktion som körs en gång efter uppgraderingen och flyttar det som behövs.
Du behöver inte adressera alla variabler individuellt. Använd memcopy, gammal flash-adress -> ram -> ny flash-adress.

T.ex från

Kod: Markera allt

struct Config_v1 {
  u16 var1;
  u16 var2;
  struct {
    u16 port;
    u16 dir;
  } inputs[2];
  u16 var3;
  u16 var4;
};
till

Kod: Markera allt

struct Config_v2 {
  u16 var1;
  u16 var2;
  struct {
    u16 port;
    u16 dir;
  } inputs[5]; // ny ver: fler I/O
  u16 var3;
  u16 var4;
};
genererar koden

Kod: Markera allt

void upgrade_config() {
  Config_v1 old_cfg = *(Config_v1*)(eeprom_addr);
  Config_v2 new_cfg;

  // kopiera data före ändringen
  memcpy(&new_cfg,
         &old_cfg,
         offsetof(Config_v1, var3));

  // kopiera data efter ändringen till ny adress
  memcpy(&new_cfg+offsetof(Config_v2, var3),
         &old_cfg+offsetof(Config_v1, var3),
         sizeof(Config_v1) - offsetof(Config_v1, var3));

  // kopiera ny struct till eeprom
  memcpy(eeprom_addr, &new_cfg, sizeof(Config_v2);

  // fråga användaren om config för de nya fälten..
}
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av arvidb »

Du blir nog så illa tvungen att definiera ett lagringsformat för datat som är separat från hur det lagras i minnet. Ge varje grupp av data (varje struct eller gruppering av structar som hör ihop "logiskt" på något sätt) ett eget ID-nummer, och inför ett versionsnummer för varje sådan grupp i lagringsformatet. Man skulle kunna inleda det lagrade datat med en tabell som indexeras med ID-nummer och som innehåller en offset till datat?

Sedan är det "bara" att skriva kod för att serialisera/deserialisera datat som finns i varje struct till och från lagringsformatet. Det vill säga: varje struct (eller logisk gruppering) blir en egen klass som kollar versionsnumret och lagrar och återläser sin egen data. (Nu gissar jag att detta är skrivet i C, men objektorienterade principer går ju att tillämpa ändå.)

På detta sätt kan man välja/speca hur man vill hantera nya eller för gamla versioner av datat. Om man inte vill skriva/inte har plats för konverteringsrutiner så slipper man i vart fall återmata in *all* data när något har ändrats.

Det är för övrigt ingen höjdare att bara spara ner structar som de är; det kan räcka med att kompilera om programmet med ny kompilatorversion eller med andra optimeringsflaggor för att saker och ting ska flytta på sig...

Edit: Ett sätt att hantera utökade structar kan vara att istället för versionsnummer helt enkelt införa ett nytt ID-nummer för den utökade varianten (eller för de utökade delarna). Då kan de gamla programmen fortsätta att läsa det gamla formatet, och nyare versioner kan dessutom läsa det nya datat om det finns.
Mr Andersson
Inlägg: 1394
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av Mr Andersson »

Det är för övrigt ingen höjdare att bara spara ner structar som de är; det kan räcka med att kompilera om programmet med ny kompilatorversion eller med andra optimeringsflaggor för att saker och ting ska flytta på sig...
Håller inte alls med om det. Jag har aldrig sett en struct flytta på sig om man inte medvetet pillar på alignment-inställningarna.
Se t.ex https://godbolt.org/z/G4EbDN där flera olika kompilatorer, plattformar och optimeringsnivåer alla får samma resultat.
Användarvisningsbild
arvidb
Inlägg: 4537
Blev medlem: 8 maj 2004, 12:56:24
Ort: Stockholm

Re: Hur löser man problemet med olika databasversioner vid u

Inlägg av arvidb »

Cool sida, tack för den länken!

Många anekdoter om att något fungerar är ju inget bevis för att det alltid fungerar. Och det finns ingenting i C- eller C++-standarderna som garanterar binär kompatibilitet på detta sätt. Det finns hur mycket som helst att läsa om detta om man gör en enkel sökning på till exempel "c struct alignment standard", här är ett exempel.

Släng in ett bitfield i din kod ovan så skiter det sig för åtminstone MSP430 gcc 6.2.1 och x86 djggp 7.2.0 (har inte orkat testa med så många fler). Dessutom vore det intressant att testa med andra kodstandarder än C++11, men då finns ju inte static_assert() tyvärr. Nu använde du ju också (klokt nog) stdint-typerna vilket "nog" inte alla gör. De mer ospecade typerna (int och så vidare) kan säkert ge andra resultat på en del arkitekturer.

Kul ändå att se att det verkar bli samma resultat med -Os som med -O2 med de flesta kompilatorer!
Skriv svar