プロペラのpthread実装がどのようなコードになっているのか、非常に気になるところです。
その前にひとまず、pthreadライブラリを使ってマルチタスクがお手軽に出来るのか?を実験をしてみることにしました。

以下がテスト用に作成したコード。
/* LED Blink test for QuickStart board Coded by Yasuhiro ISHII */ #includePellerduinoはpthread.aをリンクしてないので、ひとまず以下のMakefileにてビルド。extern "C" { #include } #include const int pinTable[8] = { PIN_LED0, PIN_LED1, PIN_LED2, PIN_LED3, PIN_LED4, PIN_LED5, PIN_LED6, PIN_LED7 }; pthread_t th[8]; pthread_mutex_t gpio_mutex; void synchronized_digitalWrite(int port,int level); void busywait(unsigned int usecs); void* thread(void* arg) { int i; i = (int)arg; pinMode(pinTable[i],OUTPUT); while(1){ printf("thread [%d]\n",i); synchronized_digitalWrite(pinTable[i],HIGH); delay((i+1)*100); synchronized_digitalWrite(pinTable[i],LOW); delay((i+1)*100); } } void synchronized_digitalWrite(int port,int level) { pthread_mutex_lock(&gpio_mutex); digitalWrite(port,level); pthread_mutex_unlock(&gpio_mutex); } void busywait(unsigned int usecs) { volatile unsigned long cycles = usecs * (_clkfreq/1000000); volatile unsigned long then = _CNT + cycles; while((long)(then - _CNT) > 0){ // pthread_yield(); } } void setup() { int i; pthread_mutex_init(&gpio_mutex,NULL); for(i=0;i<8;i++){ pinMode(pinTable[i],OUTPUT); } for(i=0;i<8;i++){ pthread_create(&th[i],NULL,thread,(void*)i); } } void loop() { }
# Propeller build Makefile # # Yasuhiro ISHII 2012 # ishii.yasuhiro@gmail.com CROSS_ENV = propeller-elf- CC = $(CROSS_ENV)gcc CPP = $(CROSS_ENV)g++ CFLAGS = -Os -I. -fno-exceptions -mlmm -lpthread -pthread CPPFLAGS = -Os -I. -fno-exceptions -mlmm -lpthread -pthread LCFLAGS = -pthread -lpthread TARGET = target.elf OBJS = main.o DOWNLOADER = propeller-load DLOPT = -r COMMONOBJS = PellerduinoCore.o OBJS += $(COMMONOBJS) #CFLAGS += -Wall -mcog .c.o: $(CC) $(CFLAGS) -c $< .cpp.o: $(CPP) $(CPPFLAGS) -c $< $(TARGET) : $(OBJS) $(CC) -o $@ $(OBJS) $(LCFLAGS) .PHONY: clean clean: -rm $(OBJS) $(TARGET) $(COMMONOBJS) .PHONY: purge purge: -rm *~ .PHONY: download download: $(DOWNLOADER) $(DLOPT) $(TARGET)コードはPellerduinoCoreからの呼び出しになっているので、Arduino同様、setup()→loop()で実行されます。
setup関数内で、I/O操作用のmutexをpthread_mutex_init関数で行った後、pthread_create関数で8スレッド起動しています。digitalWriteは同一ポート資源のコントロールをするので、スレッドからは、mutexで排他性を確保したsynchronized_digitalWriteを呼ぶようにしています。
それぞれのスレッドにそれぞれ1つのLEDを点滅させるのですが、スレッドに渡す引数の値で点滅周期が変化するようにしているので、バラバラの点滅パターンになっているように見えるはずです。
loop関数は空関数で何もしません。
動画はこちら。
なんとなく、Arduinoっぽいコードの枠組み内にpthreadを使用したマルチタスクの処理とか非常に不思議な感じのコードになってますが、以下の動画のように、なんとなくうまく動いてるようです。
複数のcogが使われているのか否かなどは、調べていきたいと思います。
もしかすると、複数cogで実行している場合、gpioのmutexは不要かもしれません。(I/Oの資源も個々に独立しているのなら)
コードは以下のPellerduinoCoreにも入っています。
https://github.com/yishii/PellerduinoCore
Netduino(Arduinoピンコンパチ.NETマイコンボード)
posted with amazlet at 12.09.26
Secret Labs LLC
売り上げランキング: 59733
売り上げランキング: 59733
Pthreadsプログラミング
posted with amazlet at 12.09.26
Bradford Nichols Dick Buttlar Jacqueline Proulx Farrel
オライリー・ジャパン
売り上げランキング: 238987
オライリー・ジャパン
売り上げランキング: 238987