Sida 1 av 2
Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 11:08:19
av TomasL
I följande kod:
Kod: Markera allt
typedef enum {PUMP_FOLLOW=0, PUMP_ON} Pump_drift_enum;
Pump_drift_enum KB_Pump_varmedrift_e;
där
"KB_Pump_varmedrift_e" är satt till "PUMP_FOLLOW"
följande kod funkar INTE (dvs IF'en är falsk)
Kod: Markera allt
if(global_inst.KB_Pump_varmedrift_e == PUMP_FOLLOW) {
ej heller
Kod: Markera allt
if(global_inst.KB_Pump_varmedrift_e == 0) {
däremot funkar följande
Kod: Markera allt
debug = global_inst.KB_Pump_varmedrift_e;
if(debug == PUMP_FOLLOW) {
Vad i jösse namn är det som händer.
Ickefungerande assembler ser ut så här:
Kod: Markera allt
205: if(global_inst.KB_Pump_varmedrift_e == 0) {
9D068F34 3C02A000 lui v0,0xa000
9D068F38 244215E0 addiu v0,v0,5600
9D068F3C 8C42084C lw v0,2124(v0)
9D068F40 14400008 bne v0,zero,0x9d068f64
9D068F44 00000000 nop
Fungerande
Kod: Markera allt
202: debug = global_inst.KB_Pump_varmedrift_e;
9D068EFC 3C02A000 lui v0,0xa000
9D068F00 244215E0 addiu v0,v0,5600
9D068F04 8C42084C lw v0,2124(v0)
9D068F08 A7C20024 sh v0,36(s8)
206: if(debug == PUMP_FOLLOW) {
9D068F24 97C20024 lhu v0,36(s8)
9D068F28 14400008 bne v0,zero,0x9d068f4c
9D068F2C 00000000 nop
Har inte tagit med all kod i assemblerlistningarna, enbart den som är relevant i If-arna
Processor PIC32MX695, MPLAB IDE (ej MPLAB-X)
Language tool versions: pic32-ar.exe v2.02, pic32-gcc.exe v2.02, pic32-ld.exe v2.02, pic32-ar.exe v2.02
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 11:31:44
av Klas-Kenny
Vad säger debuggern om du stoppar på if'en i de båda fallen?
Edit: Hur är global_inst deklarerad?
Hur blir KB_Pump_varmedrift_e plötsligt medlem i den?
Re: Vad i helsike händer, IF-sats funkar inte, [LÖST]
Postat: 30 maj 2018, 14:39:34
av TomasL
Så nu hittade vi felet, en liten slamkrypare.
Det visade sig att en enum i PIC32/MIPS/GCC-världen är en 32bitars variabel.
Vårt menysystem sparade bara ned de lägre 16 bitarna, samt att variabeln i fråga inte var initierad.
Detta sammantaget gjorde att de övre 16 bitarna i variabeln läste skräp, vilket gjorde att det inte funkade.
Eftersom inställningsvärdet, lagras i ett SPI-minne, så var det bara att skriva om minnet med alla 32 bitar.
Därefter funkar det som tänkt är.
Dock får vi nog fundera på hur vi skall validera det hela, eftersom vår menygenerator enbart genererar 16-bitars tal.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 18:05:07
av hummel
Casting, har du alla varningar, lint osv påslaget i kompilatorn? Du bör få en varning om detta.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 18:48:27
av TomasL
GCC ger inga varningar trots att allt skall vara påslaget.
-g -Wparentheses -fno-builtin -funsigned-char -Wall -Wno-pointer-sign
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 19:05:20
av hummel
Det borde väl räcka, om jag minns rätt. Har du PC-Lint, den plockar mycket dumheter.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 20:42:13
av baron3d
Går det att ändra storleken på enum i GCC ?
Skulle också vara bra att få en varning på oinitierade variabler.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 20:55:39
av SvenW
> Oinitierade variabler:
Det går med valgrind. Osäker på om den fungerar med småprocessorer.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 30 maj 2018, 21:08:51
av lillahuset
Knappast på en PIC32 utan OS.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 31 maj 2018, 00:29:25
av baron3d
Angående enum's storlek.
Bästa packning får man med "-fshort-enums"
Detta fungerar bra på egen kod lika säkert som rysk roulette.
Bättre är att använda "__attribute__ ((packed))", men fortfarande lite slumpmässigt beteende.
Ser man till att minst ett värde är större än 255 så blir det 2 bytes.
t.ex.
Kod: Markera allt
typedef enum {NOT_INVERTED=0, INVERTED=1000} __attribute__ ((packed)) inverted_enum;
Vilket fungerar bra!

Re: Vad i helsike händer, IF-sats funkar inte
Postat: 31 maj 2018, 08:46:13
av Icecap
baron3d: nu var problemet att variabeln var en 16 bitars men enum-värdet var 32 bitars...
Så att deklarera som packed lär inte göra något alls i det problem.
Grundproblemet verkar vara att det inte säkert kan deklareras vilken storlek en enum-variabel har.
"typedef enum {PUMP_FOLLOW=0, PUMP_ON} Pump_drift_enum;" anger ju att Pump_drift_enum är av typen "enum" och den är helt klart i TomasL's fall en int.
Om sedan "-fshort-enums" faktisk ställer default enum till att vara short är det ju lösningen.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 31 maj 2018, 10:08:49
av Andax
Fast om det inte är en bugg i kompilatorn borde den klaga/varna när man tilldelar ett 32-bitarsvärde till en 16-bitars variabel...
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 31 maj 2018, 10:10:33
av TomasL
så här skriver GCC om
-fshort-enums
Allocate to an enum type only as many bytes as it needs for the declared range of possible values. Specifically, the enum type will be equivalent to the smallest integer type which has enough room.
Så om jag fattar det rätt:
enum {zero, one, two};
Så blir det en int (32 bitar på pic32), som standard.
Med ovan nämda kompilatordirektiv så skall det bli en char (8 bitar) istället.
Eller har jag fattat det fel?
Andax, ja, man kan tycka att kompilatorn skall varna för att den gör en cast.
Dock i IFen så görs ju ingen cast, eller nånting.
När variabeln lagras så görs en cast, typ eller nånting.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 31 maj 2018, 13:11:04
av Icecap
Så lärdomen är att närhelst man använder enum-värden SKA man casta dom alltid.
Re: Vad i helsike händer, IF-sats funkar inte
Postat: 31 maj 2018, 14:03:28
av lillahuset
Är inte lärdomen snarare att om man envisas med enum ska man aldrig blanda dem med numeriska värden även om man "vet" vad varje enum ska ha för värde.
Felet här är väl att menysystemet returnerar numeriska värden som sedan hanteras som enum. Där kanske kompilatorn skulle ha gett felmeddelande.
Edit: Och en cast är, om man ska vara petig, alltid en öppning för fel i programmet. Jo jag använder ändå castar ganska ofta men i stort sett aldrig enum. Fy på mig.
