Pokretanje više procesa istovremeno

Može li mi neko reći kako se sa funkcijom fork() pokreće više procesa istovremeno. Ako su u pitanju dva procesa onda to nije problem kao što se da prepoznati dole u listingu. Problem je kad su u pitanju 3 procesa i više kao i strukturi ovog programa tj. u njegovom izgledu. Trebao bi znači pokrenuti pod-proces i iz njega ponovo pokrenuti pod-proces. Ovdje se koristi if “uslov”, ali kako to srediti sa npr. 5 procesa???

[code]* Startovanje novog procesa sa fork(). */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
pid_t pid;

 pid = fork();

 if (pid < 0)
 {
     printf("Greska : fork () je vratio %u.n", pid);
    exit(1);
 }

 if (pid == 0)
 {
     printf("Podproces : PID = %u. Glavni PID = %un",
             getpid(), getppid());
     sleep(2);
     puts ("Podproces se zavrsava.");
}
 else
 {
     printf("Glavni: PID = %u. Podproces = %un",
            getpid(), pid);
     puts("Glavni proces pocinje spavati.");
    sleep(60);
    puts("Glavni proces se probudio.");
 }

 return 0;

}[/code]

Evo samo jedan mali primjer, bez nekih posebnih provjera (ako se desi greska, priznajem - ja sam kriv). Program pokrece 5 procesa, saceka da se isti zavrse, a zatim ispisuje njihove pid-ove i “umre”. Svaki dijete proces ispisuje svoj pid i pid svoga roditelja. Eto, ostalo ti je vec jasno.

Izvini zbog ovako sturog objasnjenja, ali sada zurim, pa mozda kasnije uhvatim malo vremena da jos nesto dodam.


/* Startovanje novog procesa sa fork() */


 


#include <stdio.h>


#include <stdlib.h>


#include <unistd.h>


#include <sys/types.h>


#include <sys/wait.h>


 


int main(void)


{


        pid_t pid[5];


        int i;


 


        for (i = 0; i < 5; i++)


                if (!(pid[i] = fork()))


                        break;


 


        if (i == 5) {   /* roditeljski proces */


                /*


                 * Cekamo da se djeca zavrse


                 */


                for (i = 0; i < 5; i++)


                        waitpid(pid[i], NULL, 0);


 


                /*


                 * Ispisujemo njihove pid-ove


                 */


                printf("Ja sam roditelj (pid = %u) sa petoro djece:n", getpid());


                for (i = 0; i < 5; i++)


                        printf("pid[%u] = %un", i, pid[i]);


 


                exit(0);


        }


 


        /*


         * Ovo izvrsava samo child proces


         */


        printf("Ja sam dijete (pid = %u), a moj roditelj je (pid = %u)n",


                getpid(), getppid());


 


        exit(0);


}

Eto tako je kad stalno prepravljaš pitanje, odjednom jedno viška ! Dole ide dalje

Ne bi da te previše falim , ali rješenje je kako izgleda genijalno. Znači, da bi pokrenuo proces br 3 . moram pisati :

if (i == 3 ) {

*/ Ovdje dolaze komande za proces */

}

*/ Ili je pametnije da uzmem SWITCH npr: */

[code]

[code]

switch (i)

{
case 1:
*/ Komande za prvi proces */
case 2 :
*/ Komande za drugi proces */
case 3 :
*/ Komande za treci proces … itd…itd… */

 default :
    */ Proces 5 */

}

[/code][/code]

Ma nemoj se ti puno sekirati, i nemoj me nista hvaliti, nema potrebe. Stvar je samo sto sam se ja susretao sa nekim problemima sa kojim ti mozda nisi i nista vise. Posto sam dugo vremena proveo programirajuci pod DOS-om i Windows-om, mogu napraviti kvalitetnu komparaciju izmedju te “familije” MS sistema i UNIX/Linux familije koja se nalazi sa druge strane. Sa aspekta programera UNIX je toliko jednostavan, da covjek cesto ne moze da skonta o cemu se radi, jer pri susretu sa nepoznatim konceptima ocekuje uvijek nesto ekstra komplikovano. Kada u Windowsu zelim napraviti novi proces, moram pozvati funkciju CreateProcess() sa velikim brojem parametara. Ako jos koristim NT ili 2K moram sam incijalizirati security descriptor i bla bla. Puno posla oko male stvari. Kad sam prvi put vidio fork(), upitao sam se kako li ovaj sistem zna sta hocu kad funkcija nema nijednog parametra. Kad covjek vidi kako to fercera i uporedi to sa pomenutom funkcijom u Windowsu, ne moze a da se prosto ne zacudi, zadivi ili ne znam ni ja kako da se osjeca. A evo i ova digresija ode daleko…

Nego, da se vratim na tvoje pitanje. Potpuno si u pravu. Dakle, na osnovu vrijednosti varijable i mozes znati o kojem se procesu radi i korsititi if ili switch, sta god ti je draze, iako je ovo drugo sigurno elegantnije. No, kad smo vec kod ovog koda, zelio bih da iskoristim priliku i dam mali komentar koji ce mozda nekom koristiti:

        for (i = 0; i < 5; i++)  
                if (!(pid[i] = fork()))  
                        break;  

Ovaj dio koda, izvrsava petlju koja 5 puta poziva fork() i time pravi 5 novih child procesa cuvajuci pid svakog novog procesa u varijabli pid[ i]. Ukoliko je povratna vrijednost fork()-a nula, dakle ukoliko se radi o child procesu, odmah se izvrsava break u cilju izlaska iz petlje. Dakle, cim je napravljen novi child proces, isti sa izvrsenjem nastavlja ispod ove petlje. Na taj nacin je osigurano da samo roditeljski proces “pravi” djecu, tj. da su svi novi procesi djeca jednog “babe”.

        if (i == 5) {   /* roditeljski proces */
             ...
        }

Ovo je interesantna provjera o kojoj je govorio Babysitter. Posto samo roditeljski proces izvrsava petlju do kraja, samo ce u roditeljskom procesu i biti jednako 5. U prvom child procesu, i ce biti 0, u drugom 1, … u petom 4. Prema tome, uslov i == 5 tacan je samo za roditeljski proces. U nastavku slijedi analiza ovog dijela koda, koji ce izvrsiti samo roditeljski proces:

              for (i = 0; i < 5; i++)
                        waitpid(pid[i], NULL, 0);

Posto je roditeljski proces 5 puta izvrsio fork() i sacuvao pid-ove sve svoje djece u nizu pid[0] - pid[4], ovaj dio koda poziva funkciju waitpid() za svaki od child procesa, cekajuci da se svaki od njih zavrsi. Ovo je jedan od osnovnih i primitivnih nacina sinhronizacije izmedju roditelja i djece, ali je vrlo bitan iz razloga sto sprjecava pojavu zombie procesa, ali to je druga tema.

Nakon sto su se svi child procesi izvrsili, roditeljski proces nastavlja izvrsenje i ispisuje podatke o sebi i svojoj “porodici”, nakon cega isti bezuslovno umire.

Posto uslov i == 5 nije tacan ni za jedan od procesa djece, svaki od njih nastavlja sa izvrsenjem ispod if-a i ispisuje podatke o sebi i svom roditelju.

Mozda bih trebao napomenuti da je redoslijed u kome ce biti “izvrseni” child procesi nepredvidiv. Ako je potrebno osigurati odredjeni redoslijed izvrsenja ovih procesa, onda je nuzno koristenje mehanizama za sinhronizaciju, sto je opet druga tema…

Eto toliko za ovaj put …

Evo, da iskoristim priliku i popravim “nesigurni” dio koda koji pravi nove procese bez error checking-a:


        for (i = 0; i < 5; i++)

                if (!(pid[i] = fork()))

                        break;

                else if (pid[i] < 0) {

                        perror("fork");

                        exit(-1);

                }

Posto se moze desiti da i waitpid ne uspije, bilo bi dobro “osigurati” i taj dio koda:


                for (i = 0; i < 5; i++)

                        if (waitpid(pid[i], NULL, 0) < 0) {

                                perror("waitpid");

                                exit(-1);

                        }

Eto, sad je sve po PS-u (nadam se) …

Evo isprobao sam demo-program i funkcioniše baš onako kako sam zamislio.
Svi procesi počinju istovremeno i postepeno se završavaju. Ostala je još jedna kozmetička greška za koju momentalno nemam objašnjenje. Cursor mi ostaje na početku shella tj. nakon što se program završi, nepojavljuje se klasični prompt u obliku : babysitter@linux:>

mislio sam da babo-proces još čeka, ali kad utipkam ps pokaže mi da su svi procesi završeni. Pokušavao sam i main završiti sa exit(0) ali ni to nije pomoglo. hmmm…
Evo na kraju rezultat pa možda neko otkrije grešku (ili više :-))
Sretna nova i sve najbolje !

[code]/* Startovanje novog procesa sa fork() */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void)
{
pid_t pid[5];
int i;

    for (i = 0; i < 5; i++)
            if (!(pid[i] = fork()))
                    break;



else if (pid[i] < 0) {
                    perror("fork");
                    exit(-1);

}
switch (i)
{

case 0:
printf(" Proces 1 krenuon");
sleep(10);
printf(" Proces 1 zavrsavan");
break ;

case 1:
printf(" Proces 2 krenuo n");
sleep(8);
printf(" Proces 2 zavrsavan");
break;

case 2:
printf(“Proces 3 krenuon”);
sleep(6);
printf(" Proces 3 zavrsavan");
break;

case 3:
printf(“Proces 4 krenuon”);
sleep(4);
printf(" Proces 4 zavrsavan");
break;

case 4:
printf(“Proces 5 krenuon”);
sleep(2);
printf(" Proces 5 zavrsavan");
break;

default:
printf(“Ja sam roditelj (pid = %u) sa petoro djece:n”, getpid());
for (i = 0; i < 5; i++)
printf(“pid[%u] = %un”, i, pid[i]);

            exit(0);

for (i = 0; i < 5; i++)
waitpid(pid[i], NULL, 0);

                    if (waitpid(pid[i], NULL, 0) < 0) {
                            printf("Greska kod waitpidn");
                            exit(-1);

}

break;
}

    printf("Ja sam dijete (pid = %u), a moj roditelj je (pid = %u)n",
            getpid(), getppid());


    return 0;

}[/code]

Sinoć sam nekoliko puta pokušao da pošaljem ovaj post gore, i nemože pa nemože. Sad evo vidim da je tu i to 7-8 puta. Izvinjavam se radi ovoga, možda neko izbriše sve što je suvišno.
Ponekad je forum teško dostupan (manje od 1 kb/s) pa izgleda kao da se ništa ne događa. Sto se tice cursora, sredio sam i taj problem, jer code mi je trebao za jedan drugi program, gdje sam ga ugradio i tamo ne dolazi do te greškice.

:oops: :oops: :oops:

Eh, evo opet ja…

Prije nego pokusam dati odgovor na tvoje pitanje, navodim izlaz koji generise tvoj program na mom racunaru:



[kk]$ ./babysitter


Ja sam roditelj (pid = 942) sa petoro djece:


 Proces 1 krenuo


 Proces 2 krenuo


Proces 3 krenuo


Proces 5 krenuo


Proces 4 krenuo


pid[0] = 943


pid[1] = 944


pid[2] = 945


pid[3] = 946


pid[4] = 947


[kk]$  Proces 5 zavrsava


Ja sam dijete (pid = 947), a moj roditelj je (pid = 1)


 Proces 4 zavrsava


Ja sam dijete (pid = 946), a moj roditelj je (pid = 1)


 Proces 3 zavrsava


Ja sam dijete (pid = 945), a moj roditelj je (pid = 1)


 Proces 2 zavrsava


Ja sam dijete (pid = 944), a moj roditelj je (pid = 1)


 Proces 1 zavrsava


Ja sam dijete (pid = 943), a moj roditelj je (pid = 1)


_

… i ceka. Ako pritisnes ENTER, vrati se u shell. U cemu je fol?

Ako pazljivo pogledas, vidjeces da se nakon ispisa koji generise “babo” pojavio shell prompt. Odgovor na pitanje zasto je to tako lezi u slijedecem odlomku koda:



	for (i = 0; i < 5; i++)


		printf("pid[%u] = %un", i, pid[i]);





	exit(0);





	for (i = 0; i < 5; i++)


		waitpid(pid[i], NULL, 0);

Dakle, kada babo ispise pid-ove svoje djece, on odmah umre (pozove exit), i ne uspije sacekati da se njegova djeca zavrse. Zato se odmah nakon ispisa pojavljuje shell prompt, dok djeca jos uvijek ferceraju. Prvo dijete koje terminira je 5 (nakon 2 sekunde) i pojavljuje se poruka “Proces 5 zavrsava” na terminalu.

Veoma interesantan detalj je poruka koja neposredno slijedi, a koju takodje emituje 5. proces:

Ja sam dijete (pid = 947), a moj roditelj je (pid = 1)

Roditelj procesa 947 bio je, kako znamo, 942, ali u prethodnoj poruci vidimo da je roditelj sada pid 1. Zasto? Pa, nemarni babo 942 je umro prije nego sto je sacekao da se djeca zavrse, tako da je nakon njegove smrti svu njegovu djecu naslijedio “pradedo” svih procesa, tzv. “init”, ciji je pid 1.

I tako svaki od procesa djece ispisuje svoju pricu na terminalu i umire, a brizni pradedo init redovno poziva wait za svu svoju djecu i svu praunucad koji su ostali bez babe.

Pitanje zasto kursor stoji na pocetku reda i zasto se ne pojavljuje shell prompt je ovim odgovoreno. Dakle, prompt se vec pojavio (kad je umro babo-proces), i shell ceka da ti uneses neku komandu. U medjuvremenu su djeca “svrljala” po terminalu, sto nije pod kontrolom shell-a, tj. shell ne zna da je neko pisao po terminalu i zato jos uvijek ceka da uneses neku komandu. Ako sada ponovo izvrsis svoj program, i kada se kursor pojavi na pocetku novog reda, uneses npr. ls, vidjeces da je prethodna tvrdnja tacna, dakle shell ce izvrsiti ls.

Put ka rjesenju …

Najprije je potrebno izbrisati prethodno navedeni exit, koji sprjecava roditeljski proces da saceka da se djeca zavrse, dakle:



	for (i = 0; i < 5; i++)


		printf("pid[%u] = %un", i, pid[i]);





	for (i = 0; i < 5; i++)


		waitpid(pid[i], NULL, 0);

Ako sada pokrenes program, vidjeces da sve mnogo bolje izgleda, osim …

Sve je super, roditelj ceka na djecu, djeca ispisuju dobar roditeljski pid, samo se na kraju pojavljuje poruka “Greska kod waitpid”. Razlog za to je cinjenica da su djeca terminirala, a babuka opet pokusava da ceka na njih:



	for (i = 0; i < 5; i++)


		waitpid(pid[i], NULL, 0);




	/* roditelj opet ceka */

	if (waitpid(pid[i], NULL, 0) < 0) {


		printf("Greska kod waitpidn");


		exit(-1);


	}

Dakle, vidi se da su nakon prve petlje sva djeca “gotova”, a roditelj u drugoj petlji opet pokusava cekati na djecu (koja vise ne postoje) i waitpid “javlja” gresku. Prema tome, potrebno je izbaciti prvu petlju i gotovo:



/* Startovanje novog procesa sa fork() */





#include <stdio.h>


#include <stdlib.h>


#include <unistd.h>


#include <sys/types.h>


#include <sys/wait.h>





int main(void)


{


	pid_t pid[5];


	int i;





	for (i = 0; i < 5; i++)


		if (!(pid[i] = fork()))


			break;


		else if (pid[i] < 0) {


			perror("fork");


			exit(-1);


		}





	switch (i) {


		case 0:


			printf("Proces 1 krenuon");


			sleep(10);


			printf("Proces 1 zavrsavan");


			break;


		case 1:


			printf("Proces 2 krenuon");


			sleep(8);


			printf("Proces 2 zavrsavan");


			break;


		case 2:


			printf("Proces 3 krenuon");


			sleep(6);


			printf("Proces 3 zavrsavan");


			break;


		case 3:


			printf("Proces 4 krenuon");


			sleep(4);


			printf("Proces 4 zavrsavan");


			break;


		case 4:


			printf("Proces 5 krenuon");


			sleep(2);


			printf("Proces 5 zavrsavan");


			break;


		default:


			printf("Ja sam babo %u sa petoro djece:n", getpid());


			for (i = 0; i < 5; i++)


				printf("pid[%u] = %un", i, pid[i]);


			for (i = 0; i < 5; i++)


				if (waitpid(pid[i], NULL, 0) < 0) {


					printf("Greska kod waitpidn");


					exit(-1);


				}


			exit(0);


	}





	printf("Ja sam dijete (pid = %u), a moj roditelj je (pid = %u)n",


		getpid(), getppid());


	exit(0);


}

e sad moze i jedna kahva …

Vidim da imamo pravog programera u forumu i to mi je vrlo drago. Ovaj problem sa procesima sam postavljao u još nekim drugim forumima i niko mi ( bar do sada ) nije mogao dati jednostavan ili opširan odgovor kao ovdje.
Možda bi bilo dobro da ukratko ispričam zašto mi ovo treba.
Imam ovdje neki code koji pokreće istosmjerne ili step-motore preko paralelnog porta. Pošto su step-motori puno precizniji, što se tiče zaustavljanja na određenom mjestu, te regulacije njihove brzine, za mene su vrlo interesantni.
Nažalost se preko paralelnog porta daju samo dva ovakva motora upravljati, zbog toga što pp ima širinu od 8 bita. Za svaki motor su potrebna 4. Da bi upravljao više ovih motora, naručio sam jednu multiport-karticu koja ima 3 par.porta kao i patch za razne linux-kernele. Cilj je znači 6 motora upravljati, i time realizovati nešto kao robot.
Naravno, postoji mogućnost isa ili pci programiranja, ali ja sam ti tu još “tuta”.
Tvoj code sam izprobao na svom compu i pokrenuo dva motora potpuno neovisno jedan od drugog. Fazon je što istovremeno kreće aplay sa npr. Bryan Adamsom iz zvučnika pa evo pokušavam da se odigrava sve u ritmu muzike.
Znam da je smiješno ali je suuupeeer.
Kad bude sve onako gotovo kao što ja to planiram biće i par slika o ovome. Eh sad mi još samo napiši adresu na koju ću poslat flašu sekta.
Pozdrav

Posto vjerovatno upravljas relativno malim brzinama, ne znam da li si probao da sam napravis varijantu MUX/DEMUX sa nekom vrstom protokola, tako da upravljas sa svih sest motora preko jednog porta. Posto je brzina prenosa kod standardnog LPT porta 40-60 kB/sec i ako koristis 4 bita za upravljanje jednim motorom, a preostala 4 kao kontrolne linije, imaces dakle protok od recimo 48000 uzoraka u sekundi, sto podijeljeno na 6 motora znaci 8000 samplova po motoru. Ako ti to nije sporo i ako imas vremena i motivacije, mislim da je projekat interesantan, jer ukljucuje razvoj komunikacijskog protokola sa svim kontrolnim i statusnim informacijama, softvera za komunikaciju, hardverskog dijela sa demultipleksiranjem, sinhronizaciju … na kraju bi mogao napraviti i pravi drajver za svog robota, sto na Linuxu nije pretjerano komplikovano ako se malo udubis u temu.

Volio bih da cujem tvoje misljenje po ovom pitanju…

Pa, sto se tice sekta, ja inace na pijem alkohol, ali u svakom slucaju cijenim tvoju zahvalnost i zelju da mi se oduzis. Nista ti ne brini i nemoj se osjecati duznim ili nesto slicno. Meni je zaista veliko zadovoljstvo sto sam u prilici da budem jedan od onih koji mogu aktivno ucestvovati u konstruktivnim razgovorima na ovom forumu, i iskreno se nadam da cu svojim idejama i prijedlozima biti od koristi drugima.

U svakom slucaju, bilo bi mi zadovoljstvo da se upoznamo i popijemo barem kahvu ili caj, onako po BH cejfu… a moze i deutscher Kaffee wenn es dir lieber ist.

Hallo kk !
Naravno da sam razmišljao o ovom načinu upravljanja. Kao prvo, pokušao sam se informisati:Kako se informacije seriski prenose ? U objašnjenjima koja sam držao u rukama piše da se informacije na “drugom djelu” moraju memorisati tj. skupljati u memoriju prije nego se ponovo pročitaju. To mi je zvučalo kao " 3 Mjeseca posla i studiranja " pa sam odustao od te metode. Osim toga, problem bi bio kod regulacije brzine. Na drugoj strani tj. na unikatnoj pločici koja sadrži elektroniku trebalo bi ugraditi neke Timere ( Npr. NE555) koji daju takt svakom motoru. Mijenjanje brzine takta bi bila moguća dodavanjem dodatne elektronike koja “šalta” razne brzine. Ovakve pločice sam pronašao u internetu ali samo za Billy-jev sistem i koštaju 500 Eura. Nije to ni preskupo, ali sad dolazi poenta,: Software za njihovo upravljanje košta 900 Eura !!. Sa multiplexerima nisam imao mogućnost da se pozabavim ali možda sljedećih dana navratim do biblioteke pa podignem par knjiga o ovoj temi.
Program koji ja koristim direktno taktuje izlaze paralelnog porta sa “rezolucijom” od min. 10 milisekundi. Pošto koristim bipolarne motore (one male iz floppy uređaja ) sa 4 koraka po okretaju , brzina je potpuno dovoljna.
Razmišljao sam ti ja i o embedded linux i o EPROM samo ovde bi naknadno regulisanje pokreta bilo komplikovano. Ovako mi je dovoljno da editujem code, pozovem make i isprobam rezultat.
Ako ti imaš bolju ideju, odma piši !

Ako si ti zadovoljan rjesenjem, tj. ako to sve fercera kako si zamislio, onda nema potrebe da dalje komplikujes. Moj prijedlog se vise odnosio na opciju u kojoj bi ti u ulozi “radoznalog naucnika” probao da pronadjes vlastito rjesenje u vidu kartice koja ti omogucava da upravljas svojim robotom preko jednog porta. Mislim da je rjesenje sa multiplekserima prihvatljivo, ako koristis 4 linije za podatke, 3 linije za adresiranje DEMUX-a, a jednu liniju za takt koji saljes iz “utrobe” svog PC-a. Moguce su, naravno, i razne druge kombinacije, ali je poenta u cinjenici da mozes koristiti takt iz racunara umjesto hardverskih tajmera na plocici, cime izbjegavas nepotrebnu “muku” oko elektronike za regulaciju brzine motora i postizes 100% sinhronizaciju izmedju softvera i motora.

Ovo ti je nesto kao “beta”-ideja “iz rukava”, pa odluci da li ti moze koristiti…

:shock: Multiplexeri , kao što sam vidio , omogućuju serisko prenošenje informacija. Sad se za mene postavlja pitanje kako da dvije informacije istovremeno prenesem. Za okretanje motora potrebno je u određenim intervalima istovremeno prenijeti dva bita. Pošto mux. sa svakim taktom prenosi jednu onformaciju, trebalo bi uzeti 4 mux-a za svaki bit i adresiranjem odrediti koji bitovi da se aktiviraju. Eh, sad je problem kako istovremeno poslati dvije adresse preko tri voda ( žice) . Dali to znači da bez memorije neide ?

Eh, rekoh, sto peglam covjeka samo sa prijedlozima. Bolje bi bilo da nesto i skiciram. Pa, evo tu je jedno idejno rjesenje za demultipleksiranje i memorisanje:

Sa lijeve strane je LPT port, a desno su ulazi za jedan od motora (M0-M3). Linije D0-D3 predstavljaju linije podataka koje treba proslijediti do motora. A0-A2 su adresne linije, a clk je signal koji sluzi za omogucavanje, tj. onemogucavanje promjene stanja flip-flopova. Memorija, o kojoj si govorio, moze se realizirati kao sto je prikazano pomocu RS flip-flopova sa dodatnim ulazom za takt (ili sto bi svabo rek’o: “takt-zustands-gesteuerte RS Flipflops”).
Peti demultiplekser je tu da dozvoli promjenu stanja samo trenutno adresiranog motora (naravno, ako je clk=1).

Eto, to je otprilike ideja. Nije nista skupo, a nema ni puno posla… Sad je do tebe…

Pa kad smo se već zadubili u ovu temu zašto da nenađemo rješenje? Ja sam ti ovo slično zamislio, samo kod moje varijante koristim JK Master Slave Flip Flopove, jer informacije kao što sam rekao moram “među-memorisati” ili kao što bi švabo reko “zwischenspeichern” :smiley:
U tvom crtežu mi nije jasno kako odrediti koji motor da bude aktivan? Ako adresarske vodove koristiš za Multiplexere, neostaje ti više mogućnosti da adresiraš motore. Osim toga sa svakim Clok impulsom pamtiš samo jednu informaciju, sa svakim sljedećim, informacija bi se gubila na pojedinom RS Flip-Flopu. Ispravi me ako griješim ! :rolleyes:
Sutra, ako budem imao vremena, ću nacrtati moju varijantu pa je pokušati ovdje odslikati .
Čujemo se sutra ili što bi švabo reko " bis Morgen

Ne znam da li sam te najbolje razumio, ali evo pokusacu da odgovorim:

Dakle, 4 DEMUX-a su za 4 linije koje idu na svaki od motora. Posto imamo 6 motora, trebaju nam DEMUX-i 1x8 sa po tri adresne linije. Kako nam ostaju po dvije slobodne linije na svakom DEMUX-u, ne bi bilo lose da usvojimo slijedecu tabelu:

+----+----+----+-------+
| A2 | A1 | A0 | MOTOR |
+----+----+----+-------+
|  0 |  0 |  0 |   1   |
|  0 |  0 |  1 |   2   |
|  0 |  1 |  0 |   3   |
|  0 |  1 |  1 |   4   |
|  1 |  0 |  0 |   5   |
|  1 |  0 |  1 |   6   |
|  1 |  1 |  0 |   x   |
|  1 |  1 |  1 |   x   |
+----+----+----+-------+

Eh, ako sad pretpostavimo da je adresiran motor 3, dakle “adresa” je 010, onda ce i na petom DEMUX-u biti izabrana linija koja vodi na takt-ulaze RS flip-flopova za motor broj 3. To znaci da ce, ako posaljes 1 na clk, biti promijenjeno stanje samo motora broj 3, jer ce taj signal “proci” samo do flip-flopova treceg motora.

Eto, mozda sam i pogodio sta si mislio. Ako nisam, nema veze, barem imamo gornju tabelu za buduce referense.

bis Mo’en

Hallo kk!
Evo cijeli mi se dan tvoj plan vrti u glavi, jer shvatio sam u čemu je stvar. Ja sam te pogrešno shvatio a sad znam da si nacrtao izvedbu samo za jedan motor.
Svoj sopstveni plan ću odbaciti, jer je previše komplikovan. Znači, svaki motor dobija 4 RS Flip Flopa koji za trenutak zapamte stanje. Sve informacije moramo slati paralelno sa clock signalom jer on mijenja stanje. Ako želimo npr. promijeniti stanje motoru.br 2 onda imamo adresu 001, donji demux šalta odgovarajući izlaz zajedno sa 4 gornja i i nformacije se prenose na 4 odgovarajuća rs flip-flopa. Sve sam razumio i pojeo bi se što prije nisam došao na tu ideju.
Sad je važno da mi nepobjegneš iz foruma, jer nadam se da imaš snage da dovršimo ovo do kraja. Vidim da planiraš demuxe upravljati softwerskim putem. To je za mene najkomplikovaniji dio posla, jer za ovu pločicu mi treba 1 vikend, a za software…neznam?? Još nešto u vezi Hardwera: Našao sam jedan klasični 8- Bit demux sa tri adresna voda ( 74138 ) u TTL izvedbi. Kod ovog demuxa su izlazi invertirani, tako da imam suprotni efekt tj. svi izlazi su 1, samo onaj aktivni je 0. Pitam se zašto su ovo uradili. Znači morao bi negirati sve izlaze. Osim naravno ako ti znaš za drugi !
Što se tiče softwera, kao prvo potreban nam je takt koji kao što si rekao dobijamo direktno iz kernela. Ovaj takt bi trebao da bude dovoljno brz da seriski prenesemo sve informacije paralelno uz njega (uz takt). Znači, na ovom taktu baziraju sve operacije .
Kao drugo tu je funkcija koja pokreće, zaustavlja, i vraća motor. Funkcija treba da mijenja stanje naših D0-D4 vodova u slijedećem redoslijedu:

korak | magnet1 | magnet2 |

1_______D0_______D2
2_______D0_______D3
3_______D1_______D3
4_______D1_______D2
5_______D0_______D2 ( kao korak 1 )

Kao što vidiš, uvijek su dva bita aktivna tj motor fura u tkz. punom koraku (vollschritt). Kod zaustavljanja motora važno je da dva zadnja bita ostanu aktivna odnosno “high” jer motor mora eksaktno stati. Najbolje bi bila jedna funkcija kojoj kao parametar predaješ adresu, brzinu i pravac.

Kad to bude gotovo, moram se pobrinuti za adresiranje, jer kao što znaš svaka informacija, odnosno takt sadrži i odgovarajuću adresu.
Ovdje mi neće trebati više procesa, ali mi sada trebaju te adrese.
Neznam kako bi ti izveo ovaj program, kao modul ili ne ? Sigurno bi bilo bolje kompajlirati kernel-modul za npr. /dev/motor0. ali je to i teško.

Vidim da ti je njemački dobar pa ako hoćeš možeš pogledati ovdje za par informacija
http://www.linux-magazin.de/Artikel/ausgabe/1998/03/Schrittmotoren/schrittmotoren.html
Samo ovo je malo stariji članak. Andreas Zickner je objavio knjigu u kojoj je opisao još bolji način za upravljanje npr. sa “Echtzeitbaustein des PC-s” sa kojim se daju veoma brzi taktovi realizirati. Ako te interesuje ovaj code, samo reci , ja ga šaljem. Eto, sutra mi dolaze one kartice o kojima sam pričao, a evo sad stojim u pola rješenja koje je na početku bilo tako nedokučivo.
Eto sad ti napiši kako bi ti strukturirao ovaj program ?

E bas mi je drago da smo se razumjeli. Bio sam malo nesiguran da li sam najbolje razumio tvoja pitanja, ali ispalo je odlicno, masallah.

To ti je tako uobicajeno. Ljudi ti daju invertovan signal, a ti to iskoristis i jednim udarcem ga ponovo invertujes i pojacas. Ako recimo imas invertovan signal D2 na nasem DEMUX-u, onda mozes uraditi “pjeske” (bez IC-a) nesto kao na slijedecoj slici, mada je po mom misljenju bolje da se ne peglas sa tranzistorima i kupis fino gotove invertere koji ti jos i pojacaju signal i dobijes super struju - alles klar!

Ja sam radio sa nekim TTL inverterima/bufferima bas na LPT portu, samo ne znam napamet koje kolo.

Za pocetak se ne moras sekirati oko modula. Moze i obican userland program kao sto si i do sada imao. Ako to proradi, onda se poslije moze napisati mali drajver u obliku modula koji ce “sjediti” na /dev/motor0 i sl. Nije neki poseban zahmet ni oko toga.

Ako “uhvatim” malo vise slobodnog vremena, probacu da se malo zarovim u temu i vidim sta mogu. Ne bi bilo lose da ti postavis neki inicijalni nacrt rjesenja, pa da o tome razgovaramo.

Da ne bi bilo zabune, pod userland programom mislim na program koji koristi /dev/port za pisanje podataka. Mislim da bi ova opcija trebala biti dovoljno brza za testiranje funkcionalnosti elektronike, a onda mozemo napisati i nas drajver.

Jedna od ideja koja mi se vrti po glavi je da nakon pisanja drajvera napravimo 6 nodova u /dev direktoriju, npr. /dev/motor0 … /dev/motor5. Svi nodovi bi morali imati zajednicki glavni (MAJOR) broj, koji odgovara “broju” naseg drajvera, dok bi im sporedni (MINOR) brojevi bili recimo 0-5. Na taj nacin bi drajver tacno “znao” o kojem se motoru radi i mogao bi izvrsiti pravilno adresiranje demultipleksera na ploci. Onda ti npr. otkucas u shellu:







$ echo left:30:1  > /dev/motor0






$ echo right:45:2 > /dev/motor4






$ echo right:oo:1 > /dev/motor5






$ echo run | tee /dev/motor0 /dev/motor4 /dev/motor5 > /dev/null





Ovo bi otprilike moglo znaciti:

(1) Pripremi motor 0 za okretanje ulijevo za 30 stepeni brzinom 1.

(2) Pripremi motor 4 za okretanje udesno za 45 stepeni brzinom 2.

(3) Pripremi motor 5 za okretanje udesno bez prestanka (dok ne dodje naredba stop) brzinom 1.

(4) Pokreni motore 0, 4 i 5

Nakon ovoga bi motori 0 i 4 izvrsili zadano kretanje i zautavili se, a motor 5 bi se nastavio kretati. Zaustavljanje motora 5 mogli bi izvesti pomocu:






$ echo stop > /dev/motor5




Ovo sve sa shellom je, svakako, sporo, ali ideja je scheduling, tj. prvo sve pripremis za pogon, a onda kazes “sad” i sve krene “odjednom”. Tada bi samo trebalo napisati lijep program koji bi olaksao ovo programiranje naseg drajvera i eto (sve ovo lijepo zvuci …).

Posto sad nosim trenerku i rukavi su mi malo uski, mozda je dio ove “ideje iz rukava” ostao u rukavu. Ali eto, bolje je i ovo sto je izaslo, nego nista.