Küsimus:
Mis juhtub, kui kasutan valet PIN-numbrit?
Anonymous Penguin
2014-02-17 21:26:30 UTC
view on stackexchange narkive permalink

Seotud: Mis juhtub, kui esineb käitamisviga?

See küsimus sarnaneb ülaltooduga, kuid see on alternatiiv olukord:

  int pin = 999; pinMode (pin, OUTPUT); digitalWrite (pin, HIGH);  

Mis juhtuks sel juhul? Koostaja võib selle tabada, kuid kui kasutaksite juhuslikku arvu, kas IDE saaks selle kätte?

Kaks vastused:
#1
+9
asheeshr
2014-02-17 22:48:05 UTC
view on stackexchange narkive permalink

Kompilaator ei tuvasta ühtegi viga ning kood kompileerib ja käivitab. Seega, et näha, mis juhtub, peame uurima telgitaguseid. Kokkuvõtte saamiseks minge lõpuni.


Teie koodi teine ​​rida on koht, kus juhtub maagia ja kuhu me peame keskenduma.

  pinMode (pin, OUTPUT);  

pinMode selle arutelu jaoks oluline osa on järgmine:

  void pinMode (uint8_t pin, uint8_t mode) {uint8_t bit = digitalPinToBitMask (pin); // Esimene eksemplar, kus pin-i kasutatakse uint8_t port = digitalPinToPort (pin); if (port == NOT_A_PIN) return; // Tee midagi}  

(Täieliku rakenduse leiate jaotisest wiring_digital.c)

Nii näib, et digitalPinToBitMask näib kasutavat vahebiti arvutamiseks pin . Edasiseks uurimiseks on digitalPinToBitMask makro, mis on määratletud jaotises Arduino.h ja mille määratlus on see ühe reaga:

  #define digitalPinToBitMask (P) (pgm_read_byte (digital_pin_to_bit_mask_PGM + (P)))  

See imeliku välimusega üks liinilaev teeb väga lihtsa ülesande. See indekseerib massiivi P th elemendi digital_pin_to_bit_mask_PGM ja tagastab selle. See massiiv digital_pin_to_bit_mask_PGM on määratletud jaotises pins_arduino.h või konkreetse kasutatava tahvli pin-kaardil.

  const uint8_t PROGMEM digital_pin_to_bit_mask_PGM [] = {_BV (0), / * 0, port D * / _BV (1), _BV (2), _BV (3), _BV (4), _BV (5), _BV (6) ), _BV (7), ...};  

Selles massiivis on kokku 20 elementi, nii et meil pole õnne. 999 indekseerib välkmälus asuva mälu asukoha väljaspool seda massiivi, mis toob kaasa ettearvamatu käitumise. Või on see?

Meil ​​on käitamisanarhia vastu veel üks kaitseliin. Selle järgmine rida funktsioonil pinMode:

  uint8_t port = digitalPinToPort (pin);  

digitalPinToPort viib meid sarnast rada pidi. See on määratletud kui makro koos digitalPinToBitMask -ga. Selle määratlus on järgmine:

  #define digitalPinToPort (P) (pgm_read_byte (digital_pin_to_port_PGM + (P)))  

Nüüd indekseerime P digital_pin_to_port_PGM th element, mis on pin-kaardil määratletud massiiv:

  const uint8_t PROGMEM digital_pin_to_port_PGM [] = {PD, / * 0 * / PD, .... PC, PC,};  

See massiiv sisaldab 20 elementi, seega on 999 jälle vahemikust väljas. Jällegi loeb see käsk välkmälust väärtuse, mille väärtuses me ei saa kindel olla. See toob edaspidi kaasa ettearvamatu käitumise.

On veel üks viimane kaitseliin. See on if kontrollige pinMode sisse digitalPinToPort:

  if (port == NOT_A_PIN) return;  

NOT_A_PIN on Arduino.h -is määratletud kui 0. Niisiis, kui tagastatud bait digitalPinToPort -ist juhtub olema null, siis pinMode ebaõnnestub ja naaseb.

Igal juhul ei saa pinMode meid anarhiast päästa. 999 on määratud hukule.


TL; DR, kood käivitatakse ja selle tulemus on ettearvamatu. Tõenäoliselt ei määrata ühtegi tihvti OUTPUT ja digitalWrite nurjuvad. Kui teil juhtub erakordselt ebaõnne, võib juhuslik tihvt olla seatud väärtusele OUTPUT ja digitalWrite väärtuseks HIGH .

On huvitav, et kontrollimisel pole piire. digitalWrite on niikuinii nii aeglane ja mahukas, poleks ebamugav panna nii kompileerimis- kui ka ajakontrolli.
Kui kõik arduino nööpnõelad on külgnevas vahemikus, siis kas nad ei saaks porti asendada == mitte nööpnõelate kontroll nööpnõelaga> BOARD_MAX_PIN kontroll, kus parda maksimaalne tihvt on mõnes päisefailis määratletud mõne ifdefi põhjal, mis plaadi tuvastab?
Te unustate, et 999 ei saa kuvada uint8_t-s, nii et see teisendatakse kõigepealt 231-ks koodiga, mis kutsub välja "pinMode". Lõpptulemus on sama: "pinMode" ja "digitalWrite" käituvad ettearvamatult ja võivad juhusliku mäluosa röövida, kui helistate neile halva pin-argumendiga.
#2
+4
TheDoctor
2014-02-17 21:50:12 UTC
view on stackexchange narkive permalink

Standardraamatukogudes on tihvtide portideks teisendamiseks mõeldud makrod, mida kasutatakse monteerimisel. Siin on need Arduino 1.0.5 Uno jaoks:

  #define digitalPinToPCICR (p) (((p) > = 0 && (p) < = 21)? (&PC (uint8_t *) 0)) # define digitalPinToPCICRbit (p) (((p) < = 7)? 2: (((p) < = 13)? 0: 1)) # define digitalPinToPCMSK (p) (((p ) < = 7)? (&PCMSK2): (((p) < = 13)? (&PCMSK0): (((p) < = 21)? (&PCMSK1): (* digitalPinToPCMSKbit (p) (((p) < = 7)? (p): (((p) < = 13)? ((p) - 8): ((p) - 14)))  

Neid on veel, kuid ma ei näita neid siin.

Usun, et teie programm lahutaks 999-st 14, mis oleks siiski brogrammi jaoks liiga suur. Seejärel prooviks see osutada massiivi digital_pn_to_bit_mask_PGM 985. elemendile, mis sisaldab ainult 20 elementi. Tõenäoliselt lõpetaks see Arduino keeramise, osutades progmemi juhuslikule kohale.



See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...