Ubuntu Suomen keskustelualueet
Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: Mistofelees - 21.11.21 - klo:12.56
-
Olen kirjoitellut ohjelmistopakettia, joka veneessä ja matkailuautossa kerää esim paikkatietoa, esittää sen paikallisesti kulkuneuvon serverin omilla nettisivuilla ja lähettää kotiserverille. Vekottimessa on näyttölaitteena 4x20 I2C LCD.
Data lähetetään LCD:lle omatekoisella C-kielisellä ohjelmalla ( ./LCDtulosta clr "$D $T UTC"@1,1 "LAT: $lat"@2,1 "LON: $lon"@3,1 )
GPS:ää luetaan omatekoisella C-kielisellä ohjelmalla, joka printtaa $GPRMC -lauseen.
Sitten alkoivat ongelmat.
Systeemi kaatui ja kone meni jumiin epäsäännöllisesti 5min - 12h ajon jälkeen. BASH:n rajallisilla työkaluilla syyn löytäminen oli todella hankalaa.
Epäilin jo muistikortteja, prosessoria ja virtalähdettäkin.
Tämä auttoi hieman, tällä pääsi näkemään, missä kone kaatui:
trap 'echo "Vika rivillä $LINENO" >> /home/bin/i2cLCD/testi.txt' ERR
samaten pitkin scriptiä sirotellut echo "Ax">>/home/bin/i2cLCD/testi.txt -lauseet
'timeout' GPS:ää kutsuvalla rivillä auttoi selviämään GPS:n jumeista
Lopullinen ratkaisu suorastaan hävettää.
- Pistetään GPS työntämään tulostuksensa tiedostoon (tiedosto tietenkin tmpfs:llä !)
- Ajetaan C-ohjelmia taustalla ('&'), jotta niistä saadaan puristettua PID
- Pistetään scripti odottamaan GPS-ohjelman kypsymistä
- Haetaan tiedostosta rivi ja jatketaan
Kaikkine roskineenkin scriptin pyörähdykseen menee n. 2 sek, joten LCD:lle tulostuskin voidaan pistää taustalle '&'. I2C LCD:n ruudun täyttämiseen menee n. 1 sek.
Scripti ja C-ohjelmat itsessään ovat niin pitkät, etten viitsi niitä pistää tähän, mutta tässä on tarjolla mekanismi, jolla GPS:n lukeminen tuntuu onnistuvan
timeout 3 /home/bin/i2cLCD/gps >$TMPFILE &
pid=$!
wait $pid
read uline < $TMPFILE
Seuraava murhe on siinä, mitä tapahtuu, kun PID:n arvo kasvaa yli naapurin aidan. Osaako systeemi aloittaa PID-laskurin nollasta, vai tuleeko overflow ?
-
Onhan sinulla ympäristömuuttujat hallussa ?
eli onko vika samanlainen, kuin aikaisemmassakin (C-kielen) kysymyksessäsi ?
Siis antaahan seuraavat oletetut arvot ?
echo ./LCDtulosta clr "$D $T UTC"@1,1 "LAT: $lat"@2,1 "LON: $lon"@3,1
echo $TMPFILE
Elikkä ongelmasi kuvauksesta puuttui arvot ainakin seuraaville ympäristömuuttujille:
echo "$D"
echo "$T"
echo "$lat"
echo "$lon"
echo "$TMPFILE"
-
Nuo eivät ole ympäristömuuttujia, vaan bash scriptin muuttujia, jotka annetaan syötteinä tuolle C-kieliselle ohjelmalle.
Jos tuon haluaisi ajaa suoraan komentoriviltä, pitäisi tietenkin antaa muuttujille ensin arvoja.
En kyllä väitä, että ympäristömuuttujatkaan olisivat aivan hanskassa, koska en yleensä tarvitse kuin muutamia.
Tuo systeemin crashi kyllä ihmetyttää. Se ei ilmeisesti voi johtua pid:n ylivuodostakaan. Eiköhän Linux sentään osaa pyöräyttää pid:n takaisin nollille, kun yläraja tulee vastaan ?
Sain juuri kaapattua kameralla virheilmoituksen, joka kuitenkin oli niin kryptinen, että menee hetki, ennenkuin pääsen sitä purkamaan.
-
Ehdottaisin seuraavaa ...
Muuta C-kielistä (gps) ohjelmaasi seuraavan laiseksi...
- Tee siihen ikuinen looppi, jossa jokaisella kierroksella odotellaan haluttu aika.
- Lähetä gps:stä tiedot tietokantaan. (Esim. mariaDB:hen).
Sen jälkeen muuta LCDTulosta-ohjelmaa ...
- Tee myös siihen ikuinen looppi, jossa jokaisella kierroksella odotetaan haluttu aika.
- Kun tietokantaan ilmestyy uusi rivi, kirjoita tulos LCD:hen eli silloin kun gps-ohjelma on lähettänyt uuden rivin.
Edit - Googlasin tutoriaalin C:n (mariaDB)-tietokannan käytöstä, joka siis näyttää toimivan...
https://www.youtube.com/watch?v=cSZvq7Kv6_0
Edit 2 - Pitää olla asennettuna mariadb ja libmariadbclient-dev paketit.
-
Tuota pitää varmaan kokeilla. En tosin tietokantojen kanssa, vaan vaikka normaalin lineaarisen tiedoston.
Kokeilinkin jo sitä, että gps tulosti suoraan tiedostoon tmpfs:llä ja se tuntui toimivan hyvin, joten siirryin käyttämään wait komentoa.
Systeemi kaatui taas hetki sitte, joten wait ei auttanut. Sattumalta llaite oli töllössä kiinni ja sain kaapattua kameralla virheilmoituksen:
-"INFO: rcu_sched detected stalls on CPUs/tasks"
Kuukkeli kertoi, että tämä saattaa olla kernelin ongelmia:
Linux-image-current-sunxi=21.08.2, 5.10.60-sunxi
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"
Koneena on Orange Pi Lite, joten jakeluna on Armbian 21.08.1
-
Ei kyllä linuxin kuuluisi tällaisista "normaaleista softista" ikinä kaatua. Eri asia on jos on kyseessä oikea kernel bugi joka aiheuttaa
kaatumisen.
Siksi epäilisin samaa kuin sinäkin että raudassa on jotain vikaa. Se saattaa hyvinkin olla mahdollista näissä rasbi kopioissa,
itsellä oli aikasemmin BananaPI joka kaatui aina välittömästi kun cpu:lle tuli enemmän kuormaa ja piirit lämpeni.
Ensiksi siis itse alkaisin tutkimaan onko kyseessä oikeasti joku rautavika vai ei.
-
Olen tässä yrittänyt keksiä tapoja rautavikojen selvittmiseen.
Pitää seuraavaksi siirtää /var/log tmpfs:ltä muistikortille. Useampiakin muistikortteja on jo kokeiltu.
Pitää myös tehdä dummy ohjelma, joka vaan kiertää kehää.
-
Pitää myös tehdä dummy ohjelma, joka vaan kiertää kehää.
Tässä on (C-kielinen)ohjelma, joka vaan kiertää kehää...
#include <random>
#include <math.h>
#include <unistd.h>
#include <iostream>
#define PI 3.14159265
int main (int argc,char **args)
{
while (1) {
for (long i=1;i<300000;i++) {
std::cout << i+1 << "," << asin((double)rand()/(double)RAND_MAX)*180.0/PI << "\n";
}
printf("\n");
sleep(1);
}
return 0;
}
Tämän ei pitäisi kaatua, mutta jos kaatuu, niin kyseessä lienee laitevika.
-
Tässä on (C-kielinen)ohjelma, joka vaan kiertää kehää...
Ei ole vaan C++
-
Tässä on (C-kielinen)ohjelma, joka vaan kiertää kehää...
Ei ole vaan C++
Jep, olet oikeassa – Siinä käytetään C++:n ominaisuuksia, vaikkei varsinainen olio-ohjelma olekaan.
-
Pistin C:n kiertämään ikuisuuskehää.
Ei tarvinnut tietokantaa, kun ohjelma tallettaa $GPRMC-lauseen tmpfs:llä olevaan tiedostoon ja pistää tiedoston pointterin heti takaisin rivin alkuun rewind-komennolla.
Tämä on nyt pyörinyt toistakymmmentä tuntia, vaikka nostin prosun nopeuttakin
Pistää miettimään, mihin kerneli kompastui, kun scripti kutsui C:llä kirjoitettua ohjelmaa toistuvasti tuhansia kertoja
do{ // Ikuisuussilmukka:
do {
len=0;
line[0]='\0';
do{ // Luetaan lausetta portista. Max pituus 88mrk
c=serialGetchar(usart);
if ((35<c)&&(c<90)&&(len<88)){ // Rajataan merkistöä ja pituutta
strncat(line, &c, 1);
len++;
}
if (len>87){
line[0]='\0'; len=0; // Tuli roskarivi, liian pitäkä.
}
}while(c!=10); // Kierretään rivin loppuun asti:
}while(strncmp("$GPRMC",line,6)!=0); // Kierretään, kunnes on saatu $GPRMC-rivi haaviin:
uline[0]='\0'; // Tyhjennetään array:
memmove(uline, line+7, len); // $GPRMC pois lauseen alusta
rewind(fout); // pointteri tiedoston alkuun. Tulostetaan samalle riville
fputs(uline, fout);
}while(1); // Ikuisuussilmukka ei katkea normaalikeinoin, closet ovat turhat
-
Kun/jos saat kaatumisen toistumaan niin katso syslogista kyseistä kohdasta olisiko jotain vihjettä mitä on tapahtunut.
-
Tämä on nyt pyörinyt 20 tuntia ongelmitta. En viitsi palauttaa edellistä tilannetta vain testauksen takia. Tämän kanssa on nyhrännyt niin monta päivää, että pitää jo päästä seuraavan projektin kimppuun.