Eco Datagrabber
Use Eco to control firefox up and down
先到你想上傳的資料夾裡面 git init 然後add一個file git add README 通知git,現在是第一次送出 git commit -m 'first commit' 上傳到某一個人的git Repository git remote add origin git@github.com:xwaynec/test.git push上git git push origin master

再來要處理如果function size大於一個page size的情況,也就是說要把一個function放到多個page裡面。我的作法是,如果function foo是二個page大小的function,那就把這個function拆成foo、foo_2。分別把這二個function放到三個page裡面。
main.src裡面是
;LCALL _foo
MOV ECO_PAGE_ADDR,#HIGH (_foo)
MOV ECO_PAGE_ADDR+01H,#LOW (_foo)
LCALL eco_page_manager
接著在_foo這個page的結束地方要修改一下
MOV ECO_PAGE_ADDR,#HIGH (_foo_2)
MOV ECO_PAGE_ADDR+01H,#LOW (_foo_2)
LCALL eco_page_manager
RET
因為這邊要跳到另外一個page的起始位置,但是這邊是使用LCALL的緣故,在呼叫了eco_page_manager之前,stack pointer會存下一行的address,因此在這邊結束的地方要加一個RET,讓stack pointer再pop回一開始call foo的下一行,也就是在main裡面。
這邊要討論的問題很多0rz,手動改code已經很麻煩了,更何況要寫成script的方式來做自動化。
1.計算function要從哪裡切,手動改的話可以避開切到for loop。parsing asm code,我不知道要怎麼樣可以避開0rz。
2.二個page之間的溝通
3.還沒想到XD

另外在eco_page_manager裡面也要做修改,原本的做法是eco_page_manager首先取得function在ECO_PAGE_ADDR的function address,接著去判斷這個function的page ID是不是在page table裡面,處理完之後就LCALL到那個特定的address。
如果原本的function有parameter的話,這邊就必須要做修改,在
MOV DPH,ECO_PAGE_ADDR
MOV DPL,ECO_PAGE_ADDR+01H
LCALL ?C?ICALL2
跳到user function之前,必須要
MOV SPI_CTRL,ECO_PAGE_SPI_CONN
MOV R0,#LOW (ECO_PAGE_REGISTER3)
MOV A,@R0
MOV R3,A
MOV R0,#LOW (ECO_PAGE_REGISTER2)
MOV A,@R0
MOV R2,A
MOV R0,#LOW (ECO_PAGE_REGISTER1)
MOV A,@R0
MOV R1,A
MOV R0,#LOW (ECO_PAGE_REGISTER5)
MOV A,@R0
MOV R5,A
1.把ECO_PAGE_SPI recover到spi_ctrl,因為eco_page.c要用到eeprom,所以在進來eco_page_manager之前要把spi mode去備份,等eco_page_manager做完事之後,在把spi mode調回user function原本的mode。
2.這邊只列出R3,R2,R1,R5四個Register的情況,不過應該是R1~R7七個Register都要處理,因為eco_page_manager要統一都可以處理各個function才行,我們不知道使用者and Keil C51 compiler會如何把parameter分配到哪幾個Register(應該說是有規則,但是我們要能處理每一個情況就必須要把在eco_page_manager裡都處理),在compile time階段,我們利用python把使用者的asm code做些修改,在這邊我們知道使用者的code,把parameter分配到哪裡,因此我們只要取代其中的R3,R2,R1,R5。進入eco_page_manager之後,我們勢必要把idata ECO_PAGE_REGISTER1~R7的value都放回register裡面,這樣跳進user function之後,會用到的就是會用到,不會用到的就沒差。

blink_led()會成功,因為沒有切換spi_ctrl。E1 version的Eco因為rf和eeprom的spi是共用的,所以當使用EPM之前需要把spi_ctrl的值存起,在Eco Page Manager選完pape之後,會使用
LCALL ?C?ICALL2
來做function jump的動作,在此之前要把spi_ctrl做recover,恢復使用者function的spi的設定。
因此,要知道使用者程式使用到eeprom或是rf並且把其使用狀態記錄下來,所以在rf_send(xxx,xxx,xxx,xxx)這個C fucntion轉成asm fucntion
LCALL _rf_send
時,我要在_rf_send之前加入一個variable記錄現在spi_ctrl的value。
整個流程是
1.store spi value to ECO_PAGE_SPI
2.call eco_page_manager
3.move ECO_PAGE_SPI value to spi_ctrl
4.jump to user function

rf_send這個function去做compile出來的assembly code會是
; rf_send(dst_addr, 3, msg, 7);
368 MOV ?_rf_send?BYTE+04H,#00H
369 MOV ?_rf_send?BYTE+05H,#HIGH (msg)
370 MOV ?_rf_send?BYTE+06H,#LOW (msg)
371 MOV ?_rf_send?BYTE+07H,#07H
372 MOV R3,#00H
373 MOV R2,#HIGH (dst_addr)
374 MOV R1,#LOW (dst_addr)
375 MOV R5,#03H
Keil C51把前面二個parameter放到Register裡面,剩下來的放到internal data ram裡面,現在在執行function call的時候,在傳parameter的Register是
MOV R3,#00H
MOV R2,#HIGH (dst_addr)
MOV R1,#LOW (dst_addr)
MOV R5,#03H
接下來不是呼叫原先的function call,而是要去呼叫eco_page_manager,當進入eco_page_manager之後,我們不能確定R3、R2、R1、R5不會被用到,所以我目前的做法是,把這四個Register存在另外的idata的variable裡面,Jack和Jackal有提到另一個Register Bank做法,改天我再來看看。
因此我要利用python來parse function,並且把有parameter的function改成
MOV R0,#LOW (ECO_PAGE_REGISTER3)
MOV @R0,#00H
MOV R0,#LOW (ECO_PAGE_REGISTER2)
MOV @R0,#HIGH (dst_addr)
MOV R0,#LOW (ECO_PAGE_REGISTER1)
MOV @R0,#LOW (dst_addr)
MOV R0,#LOW (ECO_PAGE_REGISTER5)
MOV @R0,#03H
原先的instruction是MOV Rn,direct,這個instruction是24 cycle;現在改成一道指令要(24 + 24)cycle。










