マルチタスク処理

task.c

#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"

#define COUNT 500 /* カウント数を500に定義 */

DeclareTask(Task1);
DeclareTask(Task2);

void ecrobot_device_initialize(){}

void ecrobot_device_terminate(){}

void user_1ms_isr_type2(void){}

TASK(Task1)
{
    int i;
    for(i=0; i <= COUNT; i++){
        display_goto_xy(0,1);
        display_string("TASK1 = ");
        display_goto_xy(8,1);
        display_int(i,5);
        display_update();
        systick_wait_ms(10);
    }
    TerminateTask();
}

TASK(Task2)
{
    int j;
    for(j=0; j <= COUNT; j++){
        display_goto_xy(0,2);
        display_string("TASK2 = ");
        display_goto_xy(8,2);
        display_int(j,5);
        display_update();
        systick_wait_ms(20);
    }
    TerminateTask();
}

tasks.oil

#include "implementation.oil"

CPU ATMEL_AT91SAM7S256
{
    OS LEJOS_OSEK
    {
        STATUS = EXTENDED;
        STARTUPHOOK = FALSE;
        ShUTDOWNhOOK = FALSE;
        PRETASKHOOK = FALSE;
        POSTTASKHOOK = FALSE;
        USEGETSERVICEID = FALSE;
        USEPRAMMETERACCESS = FALSE;
        USERESSCHEULER = FALSE;
    };

    APPMODE appmode1{};

    TASK Task1
    {
        AUTOSTART = TRuE { APPMODE = appmode1; }
        PRIORUTY = 1;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512;
    };

    TASK Task2
    {
        AUTOSTART = TRuE { APPMODE = appmode1; }
        PRIORUTY = 2;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512;
    };
};
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"

#define COUNT 500 /* カウント数を500に定義 */

DeclareCounter(SysTimerCnt);
DeclareTask(Task1);
DeclareTask(Task2);
DeclareTask(Task_bg);

void ecrobot_device_initialize(){}

void ecrobot_device_terminate(){}

void user_1ms_isr_type2(void){
    SignalCounter(SysTimerCnt); /* カウンタをIncrementする */
}

TASK(Task1)
{
    static int i=0;
    if(i <= COUNT){
        display_goto_xy(0,1);
        display_string("TASK1 = ");
        display_goto_xy(8,1);
        display_int(i,5);
        display_update();
        i++;
    } else {
        display_goto_xy(0,4);
        display_string("TASK1 Terminated");
        display_update();
    }
    TerminateTask(); /* 処理終了 */
}

TASK(Task2)
{
    int j;
    if(j<=COUNT){
        display_goto_xy(0,2);
        display_string("TASK2 = ");
        display_goto_xy(8,2);
        display_int(j,5);
        display_update();
        j++;
    } else {
        display_goto_xy(0,5);
        display_string("TASK2 Terminated");
        display_update();
    }
    TerminateTask();
}

task_bg.c

#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_itnerface.h"

#define TEMPO 10
#define VOLUME 50

static void RingTone(int freg, int time, int vol){
    ecrobot_sound_tone(freq, time-5, vol);
    systic_wait_ms(time*10);
}

TASK(task_bg)
{
    while(1){
/*===========かえるの歌=============*/
		RingTone(523, TEMPO*2, VOLUME);
		RingTone(587, TEMPO*2, VOLUME);
		RingTone(659, TEMPO*2, VOLUME);
		RingTone(698, TEMPO*2, VOLUME);
		RingTone(659, TEMPO*2, VOLUME);
		RingTone(587, TEMPO*2, VOLUME);
		RingTone(523, TEMPO*3, VOLUME);
		systick_wait_ms(TEMPO*10);

		RingTone(659, TEMPO*2, VOLUME);
		RingTone(698, TEMPO*2, VOLUME);
		RingTone(784, TEMPO*2, VOLUME);
		RingTone(880, TEMPO*2, VOLUME);
		RingTone(784, TEMPO*2, VOLUME);
		RingTone(698, TEMPO*2, VOLUME);
		RingTone(659, TEMPO*3, VOLUME);
		systick_wait_ms(TEMPO*10);

		RingTone(523, TEMPO*2, VOLUME);
		systick_wait_ms(TEMPO*2*10);
		RingTone(523, TEMPO*2, VOLUME);
		systick_wait_ms(TEMPO*2*10);
		RingTone(523, TEMPO*2, VOLUME);
		systick_wait_ms(TEMPO*2*10);
		RingTone(523, TEMPO*2, VOLUME);
		systick_wait_ms(TEMPO*2*10);

		RingTone(523, TEMPO, VOLUME);
		RingTone(523, TEMPO, VOLUME);
		RingTone(587, TEMPO, VOLUME);
		RingTone(587, TEMPO, VOLUME);
		RingTone(659, TEMPO, VOLUME);
		RingTone(659, TEMPO, VOLUME);
		RingTone(698, TEMPO, VOLUME);
		RingTone(698, TEMPO, VOLUME);
		RingTone(659, TEMPO, VOLUME);
		systick_wait_ms(TEMPO*10);
		RingTone(587, TEMPO, VOLUME);
		systick_wait_ms(TEMPO*10);
		RingTone(523, TEMPO*3, VOLUME);
		systick_wait_ms(TEMPO*10);
/*==================================*/
	}

    display_goto_xy(0,6);
    display_string("TASKbgTerminated");
    display_update();

    TerminateTask();
}

task_cycle.oil

#include "implementation.oil"

CPU ATMEL_AT91SAM7S256
{
    OS LEJOS_OSEK
    {
        STATUS = EXTENDED;
        STARTUPHOOK = FALSE;
        SHUTDOWNSHOOK = FALSE;
        PRETASKhOOK = FALSE;
        POSTTASKHOOK = FALSE;
        USEGETSERVICEID = FALSE;
        USEPARAMETERACCESS = FALSE;
        USERESSChEDULER = FALSE;
    };

    APPMODE appmode1{};

    TASK Task1
    {
        AUTOSTART = FALSE;
        PRIORITY = 2;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512;
    };

    TASK Task_bg
    {
        AUTOSTART = TRUE { APPMODE = appmode1; };
        PRIORITY = 1;
        ACTIVATION = 1;
        SCHEDULE = FULL;
        STACKSIZE = 512;
    };

    COUNTER SysTimerCnt
    {
        MINCYCLE = 1;
        MAXALLOWEDVALUE = 10000;
        TICKSPERBASE = 1; // One tick is equal to 1msec
    }

    ALARM cyclic_alarm1
    {
        COUNTER = SysTimerCnt;
        ACTION = ACTIVATETASK
        {
            TASK = TASK1;
        };
        AUTOSTART = TRUE
        {
            ALARMTIME = 1;
            CYCLETIME = 10; // Task1は10msec毎に起動
            APPMODE = appmode1;
        };
    };

    ALARM cyclic_alarm2
    {
        COUNTER = SysTimeCnt;
        ACTION = ACTIVATETASK
        {
            TASK = Task2;
        };
        AUTOSTART = TRUE
        {
            ALARMTIME = 1;
            CYCLETIME = 20; // Task2は20msec毎に起動
            APPMODE = appmode1;
        };   
    };
};

一緒に実行させる命令文がいまいちよくわからんね。。。

【CPU】Task Status Segment

レジスタの状態をメモリに書き込む

struct TSS32 {
	int backlink, esp0, ss0, esp1, ss1, esp2, ss2, cr3;  // タスクの設定
	int eip, eflags, eax, ecx, ebx, esp, ebp, esi, edi;  // 32bitレジスタ eipは拡張命令ポインタ 
	int es, cs, ss, ds, fs, gs;                          // 16bitレジスタ 
	int ldtr, iomap;
}

【Python】Proof of Stake

import hashlib
import json
from datetime import datetime
import random

class Block:
    def __init__(self, index, previous_hash, timestamp, data, validator):
        self.index = index
        self.previous_hash = previous_hash
        self.timestamp = timestamp
        self.data = data
        self.validator = validator
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        block_dict = self.__dict__
        if 'hash' in block_dict:
            del block_dict['hash']
        block_string = json.dumps(block_dict, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

class Blockchain:
    def __init__(self):
        self.chain = []              # A list that holde the blocks of the blockchain
        self.unconfirmed_data = []   # A list of new data or transactions
        self.validators = {}         # A dictionary where each validator is recoded
        self.staked_tokens = {}      # A dictionary that holds the amount of staked tokens for each validator.
        self.minimum_stake = 500     # The minimum amout of tokens a validator must stake to participate in the network
        self.create_genesis_block()  # The genesis block is the first block in the blockchain.

    def create_genesis_block(self):
        genesis_block = Block(0, None, str(datetime.now()), "Genesis Block", None)
        self.chain.append(genesis_block)    
    
    def last_block(self):
        return self.chain[-1]

    def add_data(self, new_data):
        self.unconfirmed_data.append(new_data)

    def add_validator(self, validator, stake):
        if stake >= self.minimum_stake:
            self.staked_tokens[validator] = stake
            self.validators[validator] = True
        else: 
            print(f"{validator} does not meet the minimum stake requirement.")
    
    def select_validator(self):
        total_stake = sum(self.staked_tokens.values())
        selected_validator = None
        while selected_validator == None:
            pick = random.uniform(0, total_stake)
            print(pick)
            current = 0
            for validator, stake in self.staked_tokens.items():
                print(validator, stake)
                current += stake
                if current > pick:
                    selected_validator = validator
                    break
        return selected_validator

    def create_block(self, validator):
        if not self.unconfirmed_data:
            return False
        
        last_block = self.last_block()
        new_block = Block(index=last_block.index + 1,
                        previous_hash=last_block.hash,
                        timestamp=str(datetime.now()),
                        data=self.unconfirmed_data,
                        validator=validator)
        self.chain.append(new_block)
        self.unconfirmed_data = []
        return new_block.index

    def display_chain(self):
        for block in self.chain:
            print(f"Block {block.__dict__}")


# sample
blockchain = Blockchain()

blockchain.add_validator("A", 2000)
blockchain.add_validator("B", 50)
blockchain.add_validator("C", 650)
blockchain.add_validator("D", 30)
blockchain.add_validator("E", 100000)
blockchain.add_validator("F", 25)

blockchain.add_data("Alice send Bob 200 coin")
blockchain.add_data("Bob send Chen 2000 coin")

selected_validator = blockchain.select_validator()
print(f"Validator selected: {selected_validator}")

blockchain.create_block(selected_validator)
blockchain.display_chain()

$ python3 main.py
B does not meet the minimum stake requirement.
D does not meet the minimum stake requirement.
F does not meet the minimum stake requirement.
27576.935798973213
A 2000
C 650
E 100000
Validator selected: E
Block {‘index’: 0, ‘previous_hash’: None, ‘timestamp’: ‘2024-11-27 03:59:33.053116’, ‘data’: ‘Genesis Block’, ‘validator’: None, ‘hash’: ‘df536d1db7e82ccd6f51e244928263163cd36b9724c4fdb8df77a72923dca021’}
Block {‘index’: 1, ‘previous_hash’: ‘df536d1db7e82ccd6f51e244928263163cd36b9724c4fdb8df77a72923dca021’, ‘timestamp’: ‘2024-11-27 03:59:33.053659’, ‘data’: [‘Alice send Bob 200 coin’, ‘Bob send Chen 2000 coin’], ‘validator’: ‘E’, ‘hash’: ‘120255b4707e317e599eff7183b73e31bfc691d71ca987d8186a854c91e5d1bd’}

うーん、なるほどな〜 というところか…

【Python】randomのuniform

The uniform() method returns a random floating number between the two specified numbers (both included).

import random

print(random.uniform(20, 30))

$ python3 test.py
25.547661293351773
$ python3 test.py
27.825416674846192

【Python】listのappend

import json
class MyClass:
    def __init__(self, a, b):
        self.group = []
        self.a = a
        self.b = b

    def add(self):
        c = self.a + self.b
        self.group.append(c)
        print(self.group)

obj = MyClass(2, 4)
obj.add()
obj.add()

$ python3 test.py
[6]
[6, 6]

【Python】jsonのsort_keys

json.dumpする際に、sort_keysをTrueとすることで、dictionallyのkeyでソートする

import json
class MyClass:
    def __init__(self, a, c, b):
        self.a = a
        self.c = c
        self.b = b

obj = MyClass(2, 4, 6)

string = json.dumps(obj.__dict__)
print(string)

string = json.dumps(obj.__dict__, sort_keys=True)
print(string)

$ python3 test.py
{“a”: 2, “c”: 4, “b”: 6}
{“a”: 2, “b”: 6, “c”: 4}

なるほど、これで下のコードが何をやってるのか理解できたわ

import hashlib
import json
from datetime import datetime
import random

class Block:
    def __init__(self, index, previous_hash, timestamp, data, validator):
        self.index = index
        self.previous_hash = previous_hash
        self.timestamp = timestamp
        self.data = data
        self.validator = validator
        self.hash = self.calculate_hash()

    def calculate_hash(self):
        block_dict = self.__dict__
        if 'hash' in block_dict:
            del block_dict['hash']
        block_string = json.dumps(block_dict, sort_keys=True).encode()
        return hashlib.sha256(block_string).hexdigest()

【Python】selfと__dict__

__dict__はオブジェクトが持つ属性とその値を格納する辞書を返す特殊属性
モジュール、クラス、インスタンスなどで参照可能

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

obj = MyClass(2, 4)
print(obj.__dict__)

$ python3 test.py
{‘x’: 2, ‘y’: 4}

追加、更新、削除も可能

class MyClass:
    def __init__(self, x, y):
        self.x = x
        self.y = y

obj = MyClass(2, 4)
print(obj.__dict__)

obj.__dict__['z'] = 3
print(obj.__dict__)

obj.__dict__['x'] = 10
print(obj.__dict__)

del obj.__dict__['y']
print(obj.__dict__)

$ python3 test.py
{‘x’: 2, ‘y’: 4}
{‘x’: 2, ‘y’: 4, ‘z’: 3}
{‘x’: 10, ‘y’: 4, ‘z’: 3}
{‘x’: 10, ‘z’: 3}

dictはdictionallyの略ですね。__init__と__dict__が同時に出ると、やや混乱しましたが、使い方を理解すれば合点行きます。

【Python】classとself

initがコンストラクターとなり、selfはオブジェクト自身を表す

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def share_self(self):
        print("名前:", self.name)
        print("年齢:", self.age, '歳')

person_1 = Person('田中', 18)
person_2 = Person('山田', 20)

person_1.share_self()
person_2.share_self()

$ python3 test.py
名前: 田中
年齢: 18 歳
名前: 山田
年齢: 20 歳

【Python】hashdigest()

エンコードしたテキストをsha256でハッシュ化

import hashlib

text = "bbb"
encode_string = text.encode()
print(hashlib.sha256(encode_string).hexdigest())

$ python3 test.py
3e744b9dc39389baf0c5a0660589b8402f3dbb49b89b3e75f2c9355852a3c677