TinyScript Tutorial

From DiLab
Revision as of 12:44, 10 October 2012 by Atis (talk | contribs)
Jump to: navigation, search

TinyScript lietošanas pamācība

Ievads

TinyScript ir programmēšanas valoda bezvadu sensoru tīkliem. Atšķirībā no vispārīga pielietojuma programmēšanas valodām. SEAL ir daudz vienkāršāka, mazāka, un ātrāk apgūstama. Savukārt programmas, rakstītas TinyScript, ir īsākas nekā analoģiskas programmas priekš sensoru tīkliem, kuras ir rakstītas kādā no vispārēja pielietojuma programmēšanas valodām.

Programmēšanas testa laikā jums būs pieejams sensoru mezgls. Sensoru mezgls var sazināties (pa radio) ar bāzes staciju, kas atrodas vienā telpā ar to. Sensoru mezgls spēj lasīt sensorus, mikršķināt diodes utml.

Valodas sintakse

TinyScript ir šādi rezervēti atslēgvārdi:

for to next step until end if then else private shared buffer not and or

Visiem TinyScript izteikumiem jābeidzas ar noslēdzošo simbolu. Parasti tas ir semikols ';', izņemot if nosacījumus, kuriem jābeidzas ar atslēgvārdiem end if, un for ciklus, kuriem jābeidzas ar next <x>.

TinyScript sintakse ir daļēji reģistrjūtīga. Tas ir, gan variable un VARIABLE var tikt lietoti kā apzīmējumi vienam un tam pašam mainīgajam, bet VaRiaBle nevar. Ieteicams izstrādājot programmas ievērot neformālas konvencijas, lai tās būtu viegli lasāmas.

Valodas elementi

Notikuma nosaukums Izsaukšanas brīdis
Broadcast Kad tiek saņemts ziņojums no cita mezgla.
Once Kad once notikuma apstrādātājs sākotnēji tiek nosūtīts mezglam
Reboot Kad mote tiek parstartēta.
Timer0 Kad pirmais taimers nostrādā. Var tikt uzstādīts izmantojot settimer0 funkciju.
Timer1 Kad otrais taimers nostrādā. Var tikt uzstādīts izmantojot settimer1 funkciju.
Trigger Kad tiek izsaukta trigger funkcija

1. tabula: TinyScript notikumi.

Tinyscript-ide.png

1. attēls: Darba virsmas izskats

Notikumi un notikumu apstrādātāji

TinyScript programma tiek sadalīta daļās, ko sauc par notikumu apstrādātājiem (handlers), tos izsauc notikumi (events). Notikuma apstrādātājs ir kods, kas tiek izpildīts pēc kāda konkrēta notikuma iestāšanās. Notikums „iestājas”, kad šī notikuma kritēriji ir sastapti. Piemēram reboot notikums iestājas, kad mezgls tiek izslēgrts vai pārstartēts.1. tabula parāda sešus TinyScript.notikumus.

Mainīgie un datu tipi

TinyScript eksistē trīs mainīgo veidi: private, shared, un buffer. Private mainīgos var izmantot tikai notikumu apstrādātājs, tikai apstrādātājs, kas to deklarē var to izmantot. Piemēram, ja diviem notikumu apstrādātājiem ir private mainīgais saukts par counter, tad katram no viņiem ir savs neatkarīgs mainīgais. Shared mainīgais darbojas pretēji, tadejādi atļaujot diviem notikumu apstrādātājiem dalīties ar datiem. Piemēram, ja diviem notikumu apstrādātājiem ir shared mainīgais saukts par counter, tad tie abi var rakstīt un lasīt vienu un to pašu mainīgo. Shared mainīgie ir pieejami notikumu apstrādātāiem, kas atrodas uz viena sensoru mezgla, tie netiek dalīti dažādiem sensoru mezgliem.

Buffer mainīgie ir masīvi ar fiksētu maksimalo garumu un tie vienmēr ir shared tipa mainīgie. Bufferiem ir fiksēts maksimalais garums 14 vērtības. Ja Jūs mēģināsiet buffer tipa mainīgajā saglabāt vairāk kā 14 vērtības, tas izsauks buffer overflow error. Lai noskaidrotu, vai bufferis ir pilns var tikt izmantot funkcija bfull. Lai noskaidrotu buffera vērtību skaitu var izmantot funkciju bsize. Konkrētām buffera vērtībām var piekļūt izmantojot [] aiz buffera nosaukuma. Piemēram sekojošā programma iegūst vidējo vērtību bufferī:

shared size;
shared median;
buffer aggBuffer;
bsorta(aggBuffer); ! Sakārto bufferi augošā secībā
size = bsize(aggBuffer); ! Buffera vērtību skaits
median = aggBuffer[size / 2]; ! Atgriež vidējo vērtību

Lietojot tukšas figūriekavas aiz buffera nosaukuma var piekļūt pēdējai vērtībai vai pievienot jaunu vērtību. Piemēram:

val = aggBuffer[]; ! Piešķir val pēdējo vērtību bufferī un izņem to no buffera
aggBuffer[] = light(); ! Pievieno buffera beigas jaunu gaismas vertību

Visiem TinyScript mainīgajiem jābūt definētiem pirms pārējās programmas daļas. Mainīgā deklarācija sastāv no tā tipa ( private, shared, buffer), nosaukuma un semikola. Piemēram, sekojošā programma ir nekorekta (un izraisīs kompilācijas kļūdu):

shared counter; !  Deklarējam shared mainīgo counter
counter = counter + 1; ! Palielinam to
shared index; deklarējam vēlvienu shared mainīgi index. Kļūda.

TinyScript ir divi pamata datu tipi: vesels skaitlis (pozitīvi veseli skaitļi no 0 līdz 32767) un sensoru lasījumi. Piemēram:

private val;
val = 1; ! val ir vesels skaitlis
val = light(); ! val tagad ir gaismas lasījums
val = magX(); ! val tagad ir magnometra lasījums (x-ass)

Buffer tipa mainīgajam arī ir datu tips, kas norada kādas vērtības tajā var tikt saglabātas. Bufferis var saturēt tikai viena tipa vērtības. Buffera saturs un datu tips var tikt notīrīts izmantojot bclear funkciju. Bufferis pieņem tādu datu tipu, kāds piemīt pirmajai tajā ieliktajai vērtībai.

buffer bufOne;
buffer bufTwo;
bclear(bufOne); ! iztīrīt bufOne
bufOne[0] = 5; ! Ielikt 5 nulltajā pozīcijā: bufOne izmērs ir viens,  ! tips vesels skaitlis
bufOne[] = id(); ! pievienot mezgla ID.  bufOne izmērs tagad ir divi
bufOne[4] = 41; ! Pievienot 41 ceturtajā pozīcijā; bufOne izmērs ir 5, buf[2] un buf[3] ir 0
bufOne[5] = light(); ! kļūda: buffer tips ir vesels skaitlis, nevis   ! gaismas lasījums
bufOne[5] = int(light); ! pareizi; konvertē gaismas tipu uz vesela    ! skaitļa tipu.

Izteiksme

TinyScript ļauj manipulēt ar datiem izmantojot vairākas operācijas, kas kopsummā veido izteiksmes.TinyScript atbalsta loģiskās operācijas, aritmētiskās operācijas un salīdzināšanas operācijas. Loģiskās operācijas iekļauj and, or un not operatorus. Aritmētiskās operācijas iekļauj +(pieskaitīt), -(atņemt), *(reizināt) un /(dalīt). Salīdzināšanas operācijas iekļauj <(mazāks kā), >(lielāks kā), <=(mazāks vai vienāds kā), >=(lielāks vai vienāds kā), un <>(nav vienāds ar). Iekavas var tikt lietotas lai definētu darbību secību, kā arī uzlabotu lasāmību. Piemēram:

i = (5 + 2) * 2; ! Vispirms saskaita 5 un 2, tad reizina ar 2. i = 14

Datu tipi ierobežo to, kādas operācijas ar mainīgo ir korektas. Sensoru lasījumi ir nemainīgi. Jūs nevarat saskaitīt veselu skaitli ar gaismas laījumu, gaismas lasījumu ar temperatūras laījumu, vai pat gaismas lasījumu ar gaismas lasījumu. Ja Jūs gribas apstrādāt sensoru lasījumus, Jums vispirms tie ir jāpārvērš par veseliem skaitļiem izmantojot int funkciju. Piemēram:

private total;
private count;
private val;
val = light(); ! val tagad ir gaismas lasījums
val = light() / 2; ! kļūda: nevar gaismas laījumu dalīt ar 2
val = light() + magX(); ! kļūda nevar saskaitīt sensoru lasījumus
val = light() + light(); ! kļūda nevar saskaitīt sensoru lasījumus
val = int(light()); ! val tagad ir vesels skaitlis
total = total + val; ! total arī ir vesels skaitlis
count = count + 1; ! count arī ir vesels skaitlis
val = total/count; ! vidējā lasījumu vērtība.

Kontroles struktūras

Kontroles struktūras kontrolē kādā secībā programmas kods tiek izpildīts. Līdz šim visi piemēri kodu izpildīja rindiņu pa rindiņai pēc kārtas. Dažreiz mēs varētu vēlēties lai programma izlaiž dažas riundiņas, vai atkārto tās viarākas reizes. Pirmās kontroles struktūras – nosacījumi, tie liek porogrammai izpildīt vai neizpildīt kodu balstoties uz to, vai izpildās konkrētais nosacījums. Pieejamas sekojošas formas:

if <expression> then
  <block 1>
end if

if <expression> then
  <block 1>
else
  <block 2>
end if

Ja <expression> ir patiess nosacījums, tad tiek izpildīts <block 1>. Ja nosacījumam ir else daļa un <expression> ir nepatiess, tad tiek izpildīts <block 2>. Gan <block 1>, gan <block 2> arī var saturēt if-then-else nosacījumus. For konstrukcija ļauj veidot ciklus. Ir divi ciklu veidi, ar nosacījumu un bez nosacījuma. Cikli bez nosacījuma (for-to) izpildas noteiktu reižu skaitu, tie pārtrauc cikloties, kad mainīgais sasniedz noteiktu vērtību. Cikli ar nosacījumu (for-until, for-while) ciklojas līdz konkrētais nosacījums kļūst patiess. Atslēgvārds next apzīmē cikla beigas, palielina cikla mainīgo. Pēc noklusejuma cikla mainīgais katrā ciklā tiek palielināts par 1. Tomēr palielinajuma solis var tikt mainīts izmantojot stem atslēgvārdu. Kontroles ciklu struktūrai pieejamas sekojošas formas:

for <x> = <expression> to <to-constant>
  <block1>
next <x>
for <x> = <expression> to <to-constant> step <step-constant>
  <block1>
next <x>
for <x> = <expression> until <until-expression>
  <block1>
next <x>
for <x> = <expression> step <step-constant> until <until-expression>
   <block1>
 next <x>

Piemēram, sekojošais cikls izpildās 100 reizes, palielinot skaitītāju no 1 līdz 101:

private i;
private count;
count = 1;
for i = 0 to 100
  count = count + 1;
next i

Sekojošais cikls ieliek vērtības 2, 4, 6,…,20 bufferī:

private i;
buffer buf;
for i = 2 step 2 until i > 20
  buf[] = i;
next i

Jūs varat norādīt soli ar vērtību nulle, ja cikla mainīgai netiek izmantots nosacījumā un ietvertajā koda blokā. Piemēram, šis cikls liek buferī nejaušus skaitļus, līdz buferis ir pilns:

private i;
buffer buf;
for i = 0 step 0 until bfull(buf)
   buf[] = rand();
next i

Komunikācija

uart funkcijas parametrs ir buferis, ko tā nosūta pa mezgla UART. Sekojošais Timer0 notikumu pārvaldnieks izveido buferi, kas satur mezgla id un gaismas mērījumu un nosūta to pa UART. buffer data;

data[0] = id();
data[1] = int(light());
uart(data);

Jums arī nepieciešams rediģēt Once notikumu pārvaldnieku, lai sāktu Timer0.

settimer0(20); ! Darbina Timer0 ar 2 sekunžu intervālu.

Funkcija settimer0 kontrolē timer0 notikuma iestāšanās biežumu. Tās parametra mērvienība ir sekundes desmitdaļas, tātad 20 nozīmē , ka Timer0 notikums iestāsies ik pēc 2 sekundēm. Izsaucos settimer0 ar parametru 0 apstādinās to.

Ja iepriekš dotā programma darbojas, Jums vajadzētu redzēt līdzīgu izvadu kā parādīts 2. attēlā. Tīkla novērošanas logs novēro visus mezglus tīklā. Katras rindiņas sākumā ir nummurs, kas apzīmē tekošā mezgla id. Bāzes stacijas logs rāda datus, kas savākti bāzesstacijā. Jūs noteikti ievērojāt, ka, lai gan tīklā ir 4 mezgli, bāzesstacija ir saņēmusi datus tikai no mezgla 0. Tas ir tāpēc, ka tikai mote ar id 0 ir pieslēgta bāzes stacijai izmantojot UART. Ja Jūs vēlaties nosūtīt datus no citiem mezgliem uz bāzesstaciju, tad jums ir jāizmanto bcast funkcija, kas nosūta padoto bufferi visiem mezgliem, kas atrodas tīklā izmantojot broadcast ziņojumu. Ja mezgls dzird Brodadcast ziņojumu, tā aktivizē Broadcast ziņojuma notikumu apstrādātāju. Tātad Jūs varat lietot bcastbuf funkciju Broadcast ziņojuma notikumu apstrādātājā, lai saņemtu pārraidītā buffera saturu.

Programmēšanas vide

Tinyscript-ide-only.png

2. attēls: TinyScript programmēšanas vide

Uzsākot testu, jums priekšā būs TinyScript IDE atvērtā stāvoklī (2. att.).

TinyScript programmēšanas vide sastāv no vairākiem logiem. Notikumu apstrādātāju pogas norāda, kurš notikumu apstrādātājs ir izvelēts rediģēšanai vai izpildīšanai. Izvēlētā notikumu pārvaldnieka kods ir redzams programmas teksta logā un tiek izpildīts nospiežot Inject pogu apakšējā kreisajā stūrī. Kods, kas ierakstīts programmas teksta logā netiek saglabāts kamēr nav nospiesta Inject poga. Tāpēc Jūs varētu vēlēties nospiest Inject pogu pirms pārslēdzaties uz cita notikumu pārvaldnieka rediģēšanuShared tipa mainīgie, ko izmanto jūsu programma var tikt aplūkoti Shared mainīgo logā. Funkciju logs rāda sarakstu ar visām iebūvētajām funkcijām. Jūs varat aplūkot funkcijas aprakstu vārdu apraksta logā nokliksķinot uz funkcijas nosaukuma sarakstā..

Tinyscript-semantic-error.png

3. attēls: TinyScript kļūdas paziņojums

Lūdzu pievērsiet uzmanību kļūdu paziņojumiem, kad izpildat vai simulējat TinyScript programmu. Kļūdu paziņojumi palīdz jums noteikt problēmas jūsu programmā. Gramatikas kļūdas tiek noteiktas kad Jūs izpildat notikumu pārvaldnieku. Piemēram, ja jūs ielaižat drukas kļūdu un uart funkcijas vietā ierakstiet uar un mēģinat izpildīt notikumu pārvaldnieku, parādīsies logs, kā redzams 3. attēlā. Vispirms jums jānospiež OK poga un tad jādodas atpakaļ uz programmas teksta logu un jāizlabo kļūda. Jūsu notikumu parārvaldnieks nevar tikt izpildīts kamēr jūs neesat izlabojis visas gramatikas kļūdas. Pārējās kļūdas rodas izpildes laikā. Piemēram, ja jūs nepārtraukti papildināt bufferi to nekad neattīrot, ar laiku iestāsies buffera pārpildīšanās kļūda simulācijas laikā. Tādā gadījumā parādīsies ziņojums kā redzams 4. attēlā pēc kāda laika, kad darbināsiet simulāciju. Ziņojums norādīs, kurā notikumu pārvaldniekā radusies kļūda norādot kādā kontekstā tā notika.

Diemžēl kļūdas logs nepazudīs, kad būsiet izlabojis kļūdu. Jūs to varat ignorēt un vienkārši novērot kļūdas izmantojot klausīšanās logu lai pārliecinātos, ka kļūda ir izlabota.

Tinyscript-buffer-overflow.png

4. attēls: TinyScript bufera pārpildīšanās

Mēs izmantosim vienkāršu piemēru, lai demonstrētu kā darboties ar programmēšanas vidi. Sākuma izvēlieties reboot notikumu pārvaldnieku notikumu pārvaldnieku logā. Tad ievadiet sekojošu programmu programmas teksta logā:

led(17);


Ja Jūs neiegūstat līdzīgus rezultātus, pārliecinieties, ka esat ievadījusi pareizo programmu. Ja tomēr programma ievadīta pazreizilūdzu vērsieties pēc palīdzības pie instruktora.

Literatūra

Izmantots tulkojums no ABSYNTH Project materiāliem: TinyScript Manual un TinyScript Tutorial.

Skatīt arī: Mate Tutorial: Lesson 2: An Introduction to TinyScript