2014年10月24日 星期五

wxpython thread

最近寫python需要程式一直在迴圈裡面跑
如果用while true的話會當機,沒有辦法按下停止鍵
看了下面兩個非常好的reference來練習一下怎麼寫wxpython thread

Reference :


wxpython下有三個最安全的方式來寫thread
wx.PostEvent
wx.CallAfter
wx.CallLater

wx.PostEvent是最低階的方式,那那那那就先用它來寫寫看吧!!!!!

這個練習是使用者按下start,表示開始執行另一個thread,然後右邊會反覆出現紅色與綠色的按鍵還有說明,最下面顯示這個迴圈已經被跑了幾次,每次跑的時候先從txt中讀出上次已經跑的次數,然後再繼續累加(所以要先在同一個資料夾下面準備一個test_cnt.txt的檔案),順便練習讀寫file還有把file放在textctrl中顯示,按下stop則停止這個thread

wxglade建立好視窗之後要加入 from threading import Thread


這邊寫thread最主要的關鍵就是EVT_RESULT_ID


wx.frame中再用ResultEvent來跟thread溝通



wx.Frame中如果使用者按下start,則會連到thread class來執行run function


run function,先把txt中的值讀出來,int()string轉成int來累加,利用wx.PostEvent(self._notify_window,ResultEvent("Green")) 來告訴wx.Frame classGUI上要做甚麼變化,如果使用者按下STOP則會傳到abort,然後傳到run中停止執行緒




test.py
import wx

# begin wxGlade: dependencies
import gettext
# end wxGlade

# begin wxGlade: extracode
# end wxGlade

############### Definitions ###############
from threading import Thread
import time
import os
###########################################

############### Threads #######################

# Define notification event for thread completion
EVT_RESULT_ID = wx.NewId()

def EVT_RESULT(win, func):
    """Define Result Event."""
    win.Connect(-1, -1, EVT_RESULT_ID, func)

class ResultEvent(wx.PyEvent):
    """Simple event to carry arbitrary result data."""
    def __init__(self, data):
        wx.PyEvent.__init__(self)
        self.SetEventType(EVT_RESULT_ID)
        self.data = data

class WorkerThread(Thread):
    def __init__(self,notify_window):
        Thread.__init__(self)
        self._notify_window = notify_window
        self._want_abort = 0
        self.start()

    def run(self):
        
        print("Read test_cnt.txt ")
        fread = file('test_cnt.txt','r')
        while True:           
            text = fread.readline()
            if len(text) == 0:
                break;
            print text
            cnt = int(text)
        fread.close()

        while True:
            time.sleep(1)
            if self._want_abort:
                wx.PostEvent(self._notify_window,ResultEvent(None))
                return

            wx.PostEvent(self._notify_window,ResultEvent("Green"))
            time.sleep(1)
            wx.PostEvent(self._notify_window,ResultEvent("Red"))
            time.sleep(1)
            fwrite = file('test_cnt.txt','w')
            cnt += 1                    
            fwrite.write("%s"%cnt)
            fwrite.close()
            time.sleep(1)
            wx.PostEvent(self._notify_window,ResultEvent("cnt"))

            
    def abort(self):
        self._want_abort = 1
        
################################################

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.window_1 = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_3D | wx.SP_BORDER)
        self.window_1_pane_1 = wx.Panel(self.window_1, wx.ID_ANY)
        self.start = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Start"))
        self.stop = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Stop"))
        self.window_1_pane_2 = wx.Panel(self.window_1, wx.ID_ANY)
        self.light = wx.Button(self.window_1_pane_2, wx.ID_ANY, _(""))
        self.status = wx.StaticText(self.window_1_pane_2, wx.ID_ANY, _("Status\n"))
        self.cnt = wx.TextCtrl(self.window_1_pane_2, wx.ID_ANY, "")

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        ################# init function ##################
        rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
        self.cnt.SetValue(rd_log.read())
        rd_log.close()

        ################# function binding ###############
        self.Bind(wx.EVT_BUTTON,self.EVTSTART,self.start)
        self.Bind(wx.EVT_BUTTON,self.EVTSTOP,self.stop)
        EVT_RESULT(self,self.updateDisplay)
        self.worker = None
        ###################################################


        ################# function binding ###############
    def EVTSTART(self,event):
        print("Start testing")
        self.worker = WorkerThread(self)
        

    def EVTSTOP(self,event):
        print("End testing")
        self.worker.abort()

    def updateDisplay(self,event):
        if event.data is "Green":
            self.light.SetBackgroundColour(wx.Colour(0, 255, 127))
            self.status.SetLabel('Green')

        if event.data is "Red":
            self.light.SetBackgroundColour(wx.Colour(255, 0, 61))
            self.status.SetLabel('Red')

        if event.data is "cnt":
            rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
            self.cnt.SetValue(rd_log.read())
            rd_log.close()
        ###################################################

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle(_("Test"))
        self.start.SetMinSize((100, 80))
        self.stop.SetMinSize((100, 80))
        self.window_1_pane_1.SetMinSize((192, 257))
        self.light.SetMinSize((100, 40))
        self.window_1_pane_2.SetMinSize((188, 257))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4 = wx.BoxSizer(wx.VERTICAL)
        sizer_4.Add(self.start, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 20)
        sizer_4.Add(self.stop, 0, wx.LEFT | wx.TOP, 20)
        sizer_3.Add(sizer_4, 1, wx.EXPAND, 0)
        self.window_1_pane_1.SetSizer(sizer_3)
        sizer_5.Add(self.light, 0, wx.LEFT | wx.TOP, 40)
        sizer_5.Add(self.status, 0, wx.LEFT | wx.RIGHT | wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 40)
        sizer_5.Add(self.cnt, 0, wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 30)
        self.window_1_pane_2.SetSizer(sizer_5)
        self.window_1.SplitVertically(self.window_1_pane_1, self.window_1_pane_2)
        sizer_2.Add(self.window_1, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_2)
        sizer_2.Fit(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame
if __name__ == "__main__":
    gettext.install("app") # replace with the appropriate catalog name

    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    Test = MyFrame(None, wx.ID_ANY, "")
    app.SetTopWindow(Test)
    Test.Show()
    app.MainLoop()



如果用callafter則如下
import wx

# begin wxGlade: dependencies
import gettext
# end wxGlade

# begin wxGlade: extracode
# end wxGlade

############### Definitions ###############
from threading import Thread
from wx.lib.pubsub import Publisher
import time
import os
###########################################

############### Threads #######################

class WorkerThread(Thread):
    def __init__(self,notify_window):      
        Thread.__init__(self)
        self._notify_window = notify_window
        self._want_abort = 0
        self.start()

    def run(self):
        
        print("Read test_cnt.txt ")
        fread = file('test_cnt.txt','r')
        while True:           
            text = fread.readline()
            if len(text) == 0:
                break;
            print text
            cnt = int(text)
        fread.close()

        while True:
            time.sleep(1)
            if self._want_abort:
                wx.CallAfter(Publisher().sendMessage, "update", None)
                return
            wx.CallAfter(Publisher().sendMessage, "update", "Green")
            time.sleep(1)
            wx.CallAfter(Publisher().sendMessage, "update", "Red")
            time.sleep(1)
            fwrite = file('test_cnt.txt','w')
            cnt += 1                    
            fwrite.write("%s"%cnt)
            fwrite.close()
            time.sleep(1)
            wx.CallAfter(Publisher().sendMessage, "update", "cnt")
    
    def abort(self):
        self._want_abort = 1

################################################

class MyFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # begin wxGlade: MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.window_1 = wx.SplitterWindow(self, wx.ID_ANY, style=wx.SP_3D | wx.SP_BORDER)
        self.window_1_pane_1 = wx.Panel(self.window_1, wx.ID_ANY)
        self.start = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Start"))
        self.stop = wx.Button(self.window_1_pane_1, wx.ID_ANY, _("Stop"))
        self.window_1_pane_2 = wx.Panel(self.window_1, wx.ID_ANY)
        self.light = wx.Button(self.window_1_pane_2, wx.ID_ANY, _(""))
        self.status = wx.StaticText(self.window_1_pane_2, wx.ID_ANY, _("Status\n"))
        self.cnt = wx.TextCtrl(self.window_1_pane_2, wx.ID_ANY, "")

        self.__set_properties()
        self.__do_layout()
        # end wxGlade

        ################# init function ##################
        rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
        self.cnt.SetValue(rd_log.read())
        rd_log.close()

        ################# function binding ###############
        self.Bind(wx.EVT_BUTTON,self.EVTSTART,self.start)
        self.Bind(wx.EVT_BUTTON,self.EVTSTOP,self.stop)
        Publisher().subscribe(self.updateDisplay, "update")
        self.worker = None
        ###################################################


        ################# function binding ###############
    def EVTSTART(self,event):
        print("Start testing")
        self.worker = WorkerThread(self)
        

    def EVTSTOP(self,event):
        print("End testing")
        self.worker.abort()

    def updateDisplay(self,event):
        if event.data is "Green":
            self.light.SetBackgroundColour(wx.Colour(0, 255, 127))
            self.status.SetLabel('Green')

        if event.data is "Red":
            self.light.SetBackgroundColour(wx.Colour(255, 0, 61))
            self.status.SetLabel('Red')

        if event.data is "cnt":
            rd_log = open(os.path.join('', 'test_cnt.txt'), 'r')
            self.cnt.SetValue(rd_log.read())
            rd_log.close()
        ###################################################

    def __set_properties(self):
        # begin wxGlade: MyFrame.__set_properties
        self.SetTitle(_("Test"))
        self.start.SetMinSize((100, 80))
        self.stop.SetMinSize((100, 80))
        self.window_1_pane_1.SetMinSize((192, 257))
        self.light.SetMinSize((100, 40))
        self.window_1_pane_2.SetMinSize((188, 257))
        # end wxGlade

    def __do_layout(self):
        # begin wxGlade: MyFrame.__do_layout
        sizer_2 = wx.BoxSizer(wx.VERTICAL)
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_4 = wx.BoxSizer(wx.VERTICAL)
        sizer_4.Add(self.start, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 20)
        sizer_4.Add(self.stop, 0, wx.LEFT | wx.TOP, 20)
        sizer_3.Add(sizer_4, 1, wx.EXPAND, 0)
        self.window_1_pane_1.SetSizer(sizer_3)
        sizer_5.Add(self.light, 0, wx.LEFT | wx.TOP, 40)
        sizer_5.Add(self.status, 0, wx.LEFT | wx.RIGHT | wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 40)
        sizer_5.Add(self.cnt, 0, wx.TOP | wx.ALIGN_CENTER_HORIZONTAL, 30)
        self.window_1_pane_2.SetSizer(sizer_5)
        self.window_1.SplitVertically(self.window_1_pane_1, self.window_1_pane_2)
        sizer_2.Add(self.window_1, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_2)
        sizer_2.Fit(self)
        self.Layout()
        # end wxGlade

# end of class MyFrame
if __name__ == "__main__":
    gettext.install("app") # replace with the appropriate catalog name

    app = wx.PySimpleApp(0)
    wx.InitAllImageHandlers()
    Test = MyFrame(None, wx.ID_ANY, "")
    app.SetTopWindow(Test)
    Test.Show()
    app.MainLoop()



2014年10月17日 星期五

Install wxpython on raspberry pi

Reference:
http://wiki.wxpython.org/InstallingOnUbuntuOrDebian

sudo apt-get update

sudo apt-get install python-wxgtk2.8 python-wxtools wx2.8-i18n libwxgtk2.8-dev libgtk2.0-dev



restart raspberry pi

Raspberry pi with samba

Raspberry pi with samba

Reference
http://raspberrywebserver.com/serveradmin/share-your-raspberry-pis-files-and-folders-across-a-network.html

先安裝samba
sudo apt-get install samba

備份原本的smb.conf
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.org

打開smb.conf編輯
sudo leafpad /etc/samba/smb.conf &

smb.conf中的Global Settings下的兩個變數做改變
workgroup = your work group
wins support = yes

smb.conf最後加入這段
[Share]
comment = share
path = /home/pi/
read only = no
locking = no
guest ok = yes
force user = pi
writeable = yes
only guest = yes
create mask = 0777
directory mask = 0777

儲存以後重新開啟smaba就可以在網路芳鄰上看到raspberry pi
sudo service samba restart

上面的設定是沒有設定使用者人稱密碼
也可以用 smbpasswd來設定名稱為pi,之後會要求輸入兩次密碼
smbpasswd -a pi

如果是-an則只有名稱不用密碼


2014年10月15日 星期三

Microblaze axi monitor

Reference : http://www.dc.uba.ar/materias/CoDisenio/2013/c2/descargas/lab6.pdf
Spartan-6 LX9 MicroBoard Embedded Tutorial J50_EDK05-Chipscope_Debugging_13_1_1%20(1).pdf

一直想要試試看這個功能
剛好配合上最近要研究一下AXI這個bus

Microblaze上面先預留周邊的DIPLED來測試BUS
Debug → Debug Configuration → Add Chipscope peripheral → Adding axu monitor

選擇要觀察的模組 LED

microblaze上會出現兩個新的模組,在確定一次是不是接到LED BUS

打開mdmchipscope_icon_0 確定兩個的BSCAN不是重複的user 名稱,不然之後PR會有error

chipscope_axi_monitor中打開改下面設定




之後產生top layer hdl and generate bit file

打開SDK 建立peripheralapplication project
main中無限迴圈讀寫LED來方便觀察chipscope




打開chipscope , open cable
然後import project下面的microblaze\implementation\chipscope_axi_monitor_0_wrapper\chipscope_axi_monitor_0.cdc


就會看到列好的訊號在triggerwareform



然後在SDKprogram FPGA (elf file一起)
chipscope上按下T! , 就會看到即時在BUS上的訊號,chipscope不用再重新configure bit file

除了先燒進去ELF即時看以外,也可以在SDK中先不燒入elf,然後執行Debug
chipscope下面設定trigger的條件來觀察bus

Debug Configuration → Xilinx C/C++ ELF→ Debug



但是奇怪的是如果用debug的方式我看不到ready,valid 那些信號改變




2014年10月14日 星期二

8 Bits Sequence Detector

練習寫了一個Sequence Detector
網路上的範例大多都是四個bit
我練習寫了一個8 bit
對於每個state的轉換,其實不是百分之百的確定
只是寫了一些變化的testbench來測
如果遇到其他多元化的情形,FSM一定是需要再修改的

Sequence 10101100


VHDL
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity seq_det is
port(
clk   : in std_logic;  
reset : in std_logic;
enable : in std_logic;
seq_in   : in std_logic;    
seq_detected : out std_logic);  
end seq_det;
---- Pattern 10101100---------

architecture Behavioral of seq_det is

type state_type is (IDLE,S1,S2,S3,S4,S5,S6,S7,S8,S9);
signal cur_state, nxt_state : state_type;
signal seq_det,seq_det_w : std_logic;
begin

seq_detected <= seq_det;



process(clk)
begin
    if( reset = '1' ) then              
        cur_state <= IDLE;
 seq_det <= '0';
    elsif (clk'event and clk = '1') then
        cur_state <= nxt_state;
 seq_det <= seq_det_w;
    end if;
end process;


Process(cur_state,seq_in,enable)
    begin
        case cur_state is

            when IDLE =>                    
                seq_det_w <= '0';
 if( enable = '1') then
if ( seq_in = '1' ) then
nxt_state <= S1;
else  
nxt_state <= IDLE;
end if;
else
       nxt_state <= IDLE;
end if;

            when S1 => -- 1
                seq_det_w <= seq_det;
                if ( seq_in = '0' ) then
                    nxt_state <= S2;
                else  
                    nxt_state <= S1;
                end if;

            when S2 => -- 0
                seq_det_w <= seq_det;
                if ( seq_in = '1' ) then
                    nxt_state <= S3;
                else  
                    nxt_state <= IDLE;
                end if;
-
            when S3 => -- 1
                seq_det_w <= seq_det;
                if (seq_in = '0' ) then
                    nxt_state <= S4;
                else  
                    nxt_state <= S1;
                end if;

            when S4 => -- 0
                seq_det_w <= seq_det;
                if ( seq_in = '1' ) then
                    nxt_state <= S5;
                else  
                    nxt_state <= IDLE;
                end if;

when S5 => -- 1
                seq_det_w <= seq_det;
                if ( seq_in = '1' ) then
                    nxt_state <= S6;
                else  
                    nxt_state <= S4;
                end if;

when S6 => -- 1
                seq_det_w <= seq_det;
                if ( seq_in = '0' ) then
                    nxt_state <= S7;
                else  
                    nxt_state <= S1;
                end if;

when S7 => -- 0
                seq_det_w <= seq_det;
                if ( seq_in = '0' ) then
                    nxt_state <= S8;
                else  
                    nxt_state <= S3;
                end if;

when S8 => -- 0
                seq_det_w <= '1';
                if ( seq_in = '1' ) then
                    nxt_state <= S1;
                else  
                    nxt_state <= IDLE;
                end if;


            when others =>
                NULL;
        end case;
end process;  


end Behavioral;





2014年10月10日 星期五

VHDL 觀念釐清

hardware.html
http://www.synthworks.com/papers/vhdl_math_tricks_mapld_2003.pdf
http://www.csd.nutn.edu.tw/VHDL/CH4.pdf

RTL (Register Transfer level)
Rising_edge(clk) & clk'event and clk = '1'
如果clk正常工作的話兩個都可以正常使用,但是如果clk在低電位時為unknown,使用clk'event and clk = '1' 會造成沒有訊號,Rising_edge(clk)正常,rising_edge has a few extra checks built-in to make sure that you actually have an edge.,Use Rising_edge(clk) instead of clk'event and clk = '1'


std_logic,std_logic_vector & bit,bit_vector
bit : 只能用來代表'0' or '1'
std_logic : 可以用來代表七種資料型態,包括
U’(Uninitialized)
X’(Forcing Unknown)
0’(Forcing 0)
1’(Forcing 1)
Z’(High Impedance)
W’(Weak Unkonwn)
L’(Weak 0)
H’(Weak 1)
-‘(Don’t Care)

所以在程式中當確定訊號只會為0或是1的時候即可以用bit,在某些shift operator中無法使用
std_logic_vector,所以可以使用下列的函式來轉換,不用另外加library,已經在std_logic_1164

"To_bit"
"To_bitvector"
"To_StdLogic"
"To_StdLogicvector"
"To_StdULogic"
"To_StdULogicvector"

integer,signed,unsigned 轉換(Xilinx)

use IEEE.NUMERIC_STD.ALL;
<signed_sig> = TO_SIGNED(<int_sig>, <integer_size>); – integer to signed
<unsigned_sig> = TO_UNSIGNED(<int_sig>, <integer_size>); – integer to unsigned
<int_sig> = TO_INTEGER(<signed_sig>); – signed to integer
<int_sig> = TO_INTEGER(<unsigned_sig>); – unsigned to integer

Delay

Delta Delay
In VHDL simulations, all signal assignments occur with some infinitesimal delay, known as delta delay. Technically, delta delay is of no measurable unit, but from a hardware design perspective one should think of delta delay as being the smallest time unit one could measure, such as a femtosecond (fs).
這是每級預設的最小延遲
慣性延遲(inertial delay model)
可以用在程式當中,但是synthesis後會被optimized, Inertial delay is basically a default component delay
a <= b after 1ns;
wait for time expressions
wait on signal
wait until condition
wait;
這些都是不能合成的,最好只用在testbench裡面
傳遞延遲
通常用在testbench的輸入輸出,Transport delay basically represents a wire delay.

a <= transport b after 1ns;

Concurrent & Sequential Statements


Concurrent為共時性敘述,每個processblock之間為Concurrent
Sequential 為順序性敘述,process內的為Sequential



Signal & Variable


signal assignment statement Target物件 <= 表示式;
variable assignment statement Target物件 := 表示式;

Signal variable都可以指定初始值



Signal 不可以重複設定,可以用在package,entity,architecture,ports
Signal只有在process,procedure,function順時執行到時才會改變資料



variable可以重複設定,可以用在process,procedure,function
variable資料隨時可被更新
模擬時無法看到variablewaveform

Subtypes

次資料型別係用來表示一個資料型別的子集合 (Sub-Sets)

subtype SUBTYPE_NAME is TYPE_NAME [範圍宣告];

次資料型別的宣告,由一個關鍵字subtypeSUBTYPE來表示。之後的識別字為次資料型別
的名稱。關鍵字的後面的識別字用來表示所使用的原始資料型別。最後所宣告的範圍限制,
乃是對次資料型別所局限的範圍做一個定義

SUBTYPE First_ten IS INTEGER RANGE 0 to 9;

有兩種場合,需要使用到次資料型別:
(1)在訊號指定或Case指定的命令列中加以限制其資料的範圍,以控制電路合成的結果。
(2)建立一個解值(Resolved)的資料型別。


Function & Procedure
function可以用來做一些常用的數學運算,但是只能回傳一個值
Procedure function最大的差別在於它可以回傳一個以上的值,而且可以不同型態

array and records types

array types,一組資料物件
陣列資料物件中的元素,可以使用陣列的指標(Index) 來指定陣列中指定位置的元素
type BYTE is array (0 to 7) of bit;
陣列資料型別,通常使用在線性結構的一組資料中,也可以用來表示多維的陣列資料型別
也可以在使用的時候,不宣告其元素的方式來使用,增加程式設計上的彈性

records types,一組不同的資料物件所組合而成
記錄資料型別,係由一組不同的資料物件所組合而成的資料型別,而陣列中的每一個元素可
以是任意的資料型別。
# 在記錄型別內的每一個元素,都可以用一個名稱來加入設定或指定。
# VHDL電路設計語言中的記錄資料型別類似於C語言中的結構(Structure)。記錄資料型別
內的每一個元素,可以是任意的資料型別,也包含陣列資料型別與記錄資料型別均可用來當
作記錄資料型別內的元素。

type OPTYPE is (ADD, SUB, JMP);
type INSTRUCT is
record
OPCODE: OPTYPE;
SOURCE: integer;
DESTINATION: integer;
end record;