小華的部落格

搜尋此網誌

網頁

星期二, 10月 06, 2009

C語言原來不能亂放空白字元!


寫Code的過程中發現原來巨集後面不能加"空白"字元!

見下圖中紅色框框的地方,如果有空白字元會Compiler error.

星期四, 6月 18, 2009

Visual C++ 編譯器選項

最近常常在寫C語言且被編譯器的選項困擾,所以就到微軟網站找到相關的資訊。
因為怕微軟更新網站資料就消失了,因此在這邊記錄選項的部分內容,如果有興趣了解更多的人可以到經由連結到微軟網站得到更多詳細的訊息:

Visual C++ 編譯器選項
選項 用途

@

指定回應檔。

/?

列出編譯器選項。

/AI

指定一個要搜尋的目錄,以解析傳遞給 #using 指示詞的檔案參考。

/analyze

啟用程式碼分析

/arch

在程式碼產生時使用 SSE 或 SSE2 指令 (僅適用於 x86)。

/bigobj

增加 .obj 檔中可定址區段的數目

/C

在前置處理過程中保留註解。

/c

編譯而不連結。

/clr

產生輸出檔案,以便在 Common Language Runtime 上執行。

/D

定義常數和巨集。

/doc

將文件註解處理成 XML 檔案

/E

複製前置處理器輸出至標準輸出。

/EH

指定例外處理模型。

/EP

複製前置處理器輸出至標準輸出。

/errorReport

讓您直接提供內部編譯器錯誤 (ICE) 資訊給 Visual C++ 團隊

/F

設定堆疊大小。

/favor

產生已為特定 x64 架構最佳化的程式碼,或為 AMD64 和 延伸記憶體 64 技術 (Extended Memory 64 Technology, EM64T) 架構中微架構特性最佳化的程式碼

/FA

建立清單檔。

/Fa

設定清單檔名稱。

/FC

顯示在診斷測試中傳遞給 cl.exe 的原始程式檔完整路徑

/Fd

重新命名程式資料庫檔案。

/Fe

重新命名可執行檔。

/FI

前置處理指定的包含檔。

/Fm

建立對應檔 (Mapfile)。

/Fo

建立目的檔。

/fp

指定浮點行為

/Fp

指定先行編譯標頭檔的名稱。

/FR

/Fr

產生瀏覽器檔案。

/FU

強制使用某一檔名,就如同它已傳遞給 #using 指示詞一樣。

/Fx

將插入的程式碼與原始程式檔合併。

/G1

為 Itanium 處理器執行最佳化。只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供。

/G2

為 Itanium2 處理器最佳化 (預設值為 /G1 與 /G2 之間),只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供。

/GA

對 Windows 應用程式進行程式碼最佳化。

/Gd

使用 __cdecl 呼叫慣例 (僅適用於 x86)。

/Ge

啟動堆疊探查。

/GF

啟用字串共用。

/GH

呼叫攔截 (Hook) 函式 _pexit

/Gh

呼叫攔截 (Hook) 函式 _penter

/GL

啟用整個程式最佳化。

/Gm

啟用最少重建。

/GR

啟用執行階段型別資訊 (RTTI)。

/Gr

使用 __fastcall 呼叫慣例 (僅適用於 x86)。

/GS

緩衝處理安全性檢查。

/Gs

控制堆疊探查。

/GT

對使用靜態執行緒區域儲存區配置的資料支援 Fiber 安全性。

/GX

啟用同步例外處理。

/Gy

啟用函式階層連結。

/GZ

/RTC1 相同。/RTC (執行階段錯誤檢查)

/Gz

使用 __stdcall 呼叫慣例 (僅適用於 x86)。

/H

限制外部 (公用) 名稱的長度。

/HELP

列出編譯器選項。

/homeparams

在函式進入時,強制暫存器中所傳遞的參數寫入至堆疊上的位置。這個編譯器選項只適用於 x64 編譯器 (原生和跨平台編譯)

/hotpatch

建立可線上修補的影像

/I

搜尋包含檔的目錄。

/J

變更預設 char 型別。

/LD

建立動態連結程式庫。

/LDd

建立偵錯動態連結程式庫。

/link

傳遞指定的選項給 LINK。

/LN

建立 MSIL 模組

/MD

使用 MSVCRT.lib 建立多執行緒 DLL。

/MDd

使用 MSVCRTD.lib 建立偵錯多執行緒 DLL。

/MT

使用 LIBCMT.lib 建立多執行緒可執行檔。

/MTd

使用 LIBCMTD.lib 建立偵錯多執行緒可執行檔。

/nologo

隱藏登入程式的啟始資訊。

/O1

建立小型程式碼。

/O2

建立快速程式碼。

/Ob

控制內嵌展開。

/Od

停用最佳化。

/Og

使用全域最佳化。

/Oi

產生內建函式。

/openmp

在原始程式碼中啟用 #pragma omp

/Os

偏好小的程式碼。

/Ot

偏好快的程式碼。

/Ox

使用最大最佳化 (/Ob2gity /Gs)。

/Oy

省略框架指標 (僅適用於 x86)。

/QIfist

在必須從浮點型別轉換為整數型別時,抑制 _ftol (僅適用於 x86)。

/QIPF_B

根據 B CPU 逐步偵錯的 errata,不會產生指令順序,而導致意外結果(僅適用於 IPF)。

/QIPF_C

根據 C CPU 逐步偵錯的 errata,不會產生指令順序,而導致意外結果(僅適用於 IPF)。

/QIPF_fr32

不要使用上層 96 浮點暫存器(僅適用於 IPF)。

/QIPF_noPIC

產生影像加上與位置有關的程式碼 (僅適用於 IPF)

/QIPF_restrict_plabels

為不在執行階段建立函式的程式增強效能(僅適用於 IPF)。

/P

將前置處理器輸出寫入檔案。

/RTC

啟用執行階段錯誤檢查。

/showIncludes

在編譯時顯示包含檔清單。

/Tc

/TC

指定 C 原始程式檔。

/Tp

/TP

指定 C++ 原始程式檔。

/U

移除某個預先定義巨集。

/u

移除所有預先定義巨集。

/V

設定版本字串。

/vd

抑制或啟用隱藏的 vtordisp 類別成員。

/vmb

對指向成員的指標使用最佳基底。

/vmg

對指向成員的指標使用完整一般性。

/vmm

宣告多重繼承。

/vms

宣告單一繼承。

/vmv

宣告虛擬繼承。

/W

設定警告層級。

/w

停用所有警告。

/Wall

啟用所有警告,包括預設停用的警告。

/WL

從命令列編譯 C++ 原始程式碼時啟用一行錯誤和警告訊息診斷。

/Wp64

偵測 64 位元可移植性問題。

/X

忽略標準 Include 目錄。

/Y-

忽略目前組建中所有其他先行編譯標頭編譯器選項。

/Yc

建立先行編譯標頭檔。

/Yd

將完整的偵錯資訊置於所有目的檔中。

/Yl

在建立偵錯程式庫時插入一個 PCH 參考

/Yu

在建置時使用先行編譯標頭檔。

/Z7

產生 C 7.0 相容的偵錯資訊。

/Za

停用語言擴充功能。

/Zc

指定 /Ze 下的標準行為。/Za、/Ze (停用語言擴充功能)

/Ze

啟用語言擴充功能。

/Zg

產生函式原型。

/ZI

將偵錯資訊包括在與「編輯後繼續」相容的程式資料庫中。

/Zi

產生完整偵錯資訊。

/Zl

從 .obj 檔案移除預設程式庫名稱 (僅適用於 x86)。

/Zm

指定先行編譯標頭的記憶體配置上限。

/Zp

封裝結構成員。

/Zs

僅檢查語法。

/Zx

產生可偵錯最佳化程式碼,只有 IPF 跨平台編譯器或 IPF 原生編譯器才有提供


Reference


星期日, 5月 17, 2009

Intel EFI Specs資訊

整理一下以前在Intel網站抓的一些Specs資訊。
怕自己忘記去哪下載!
所以就留下筆記記錄一下!

這些都是Intel 所提供的相關文件,有興趣的可以去Intel網站抓。

ftp://download.intel.com/technology/framework/docs
















































































































































































ftp://download.intel.com/technology/framework/docs
Reference
www.intel.com

痞子英雄

最近在迷這部電視劇,真是令人熱血了起來! 好久沒看到台灣有如此棒的電視劇了!
劇中的高雄風景真的很美,讓我又有想去痞子一日遊的衝動了~

http://www.pts.org.tw/~web03/ruffian_hero/index1.htm

星期三, 5月 13, 2009

AfterG3 bit

After G3 bit : 用來設定AC電源重新供電後的系統狀態

狀態1 : S0/S1/S3 電源有問題,重新上電
1=保持S5
0=啟動

狀態2 : S4 電源有問題,重新上電
1=保持S4
0=啟動

狀態3 : S5 電源有問題,重新上電
1=保持S5
0=啟動

星期二, 4月 21, 2009

C/C++ Compiler Intrinsics

Compiler Intrinsics 的相關連結,因為最近寫C語言時常在使用所以收集此連結!

EX:

__debugbreak();
__enable();
__disable();

http://msdn.microsoft.com/zh-tw/library/26td21ds.aspx

星期三, 1月 21, 2009

老程式也有它的好處

大家都知道debug.com的用法,不過他還有一個應用的方式是我經常使用的!
剛好前陣子公司同事也有分享這個用法,所以就順便把他在做個簡單的介紹。

老程式Debug.com 有支援輸入/輸出導向,也就是以前DOS下的 ">" 跟"<" 符號所做的事情, 而他的用法很簡單,你只要在一個文字檔中先寫好你要做的事情,然後導入到Debug.com中 就可以了,而Debug.com就會依照你的文字檔的動作去做事情! 例如原本你使用debug.com時你做了下面的動作 -d
-q

那麼你就可以寫成一個Test.txt,然後裡面的內容是:
d
q

接著進入DOS Cmd prompt ,導入這個文字檔給debug.com 例如:
C:\> debug < test.txt

這樣子debug就會自動幫你執行d指令,還有q 離開debug.com.

而下面是一個Dump PIRQ的批次檔,我會自己去F Segment內找到'$PIR' 的位址,然後透過D指令去Dump 這個記憶體,接著把Dump的內容寫到一個檔案中:

@ECHO OFF
REM ============= Find PIRQ ===================
ECHO. s f000:0 ffff '$PIR' > FindPIRQ.txt
ECHO. q >> FindPIRQ.txt
debug <> PIRQAddr.txt

REM ============= Set variable ===================
FOR /F %%A in ('FINDSTR /C:"F000" PIRQAddr.txt') do SET FSEG=%%A

REM ============= Dump PIRQ ===================
ECHO. d %FSEG% > DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. d >> DumpPIRQ.txt
ECHO. q >> DumpPIRQ.txt

debug <> Pirq.txt

ECHO.
ECHO. Output: PIRQ.txt
ECHO.

DEL FindPIRQ.txt
DEL PIRQAddr.txt
DEL DumpPIRQ.txt
pause


底下是我產生的文字檔內的內容:
- d F000:DE80

F000:DE80 24 50 49 52 00 01 60 01-FF FF 00 00 86 80 2E 12 $PIR..`.........
F000:DE90 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
F000:DEA0 00 00 00 F8 DE 00 F8 DE-00 F8 DE 00 F8 DE 00 00 ................
F000:DEB0 00 38 60 E0 1C 00 F8 DE-00 F8 DE 00 F8 DE 00 00 .8`.............
F000:DEC0 00 08 60 E0 1C 00 F8 DE-00 F8 DE 00 F8 DE 00 00 ..`.............

星期日, 1月 18, 2009

人生無常

『人生無常』~ 以前總覺得『無常』是無法接觸到的,是看不到摸不到的! 一旦它讓你看到/接觸到時真是令人難以承受之痛!

去年,2008.11.18 我敬愛的叔叔走了,當時很難過;一個我從小當成典範的長輩一個疼愛我的長輩離開了我,但想到他能夠自癌病中解脫,能夠到達另一個世界去未嘗不是一種新的祝福!

但人生就是如此無常,二個月後的昨天2009.01.18,我自小照顧我的奶奶因為心肌梗塞突然送進加護病房急救,在我回到苗栗時奶奶就已經走了! 最後一面沒有見到,心好痛! 在陪伴著、看著她安詳的躺在那時,淚水一直停不下來!

『人生無常』,希望大家能夠好好珍惜身邊的親友與你最愛的人! 平凡的幸福才是真正的幸福,一早起來你的親友和你愛的人能夠笑著跟你打聲招呼,這種平凡的幸福在此刻的我真的難以擁有啊!

星期日, 1月 11, 2009

EFI 的新體驗~

以前在做案子的時候只管如何去把OEM/ODM features做出來,所以比較少時間去慢慢的消化EFI code的內容,其實在EFI中有很多小地方的事情是以前學C語言的時候從來都沒有注意過的事情!而這些小地方也讓我對C語言有了更進一步的體驗~

像是最近研究EFI code的過程中發現了一個好玩的東西,原來C也有類似 Strong/Weak 的寫法!
以前一直笨笨的想說C要怎麼去做這部份的東西,還一直以為做不到! 原來這些東西都已經有參考範例在EFI code之中了! 只是以前壓根子都沒想過原來C可以這樣玩~在慢慢消化EFI code的過程中還真的是驚奇不斷咧!

從最近學習EFI code的過程之中,真的讓我對C語言有了更深一層的了解;在此時回頭去想想以前自己在學校中老是以為我已經對C有一定層度的認知~現在才發現 "原來我只是個井底之蛙啊"....

星期日, 12月 28, 2008

幾首電視上聽到的歌

最近一個人租房子住在外面,所以回到家都很少會去開電視!
而昨天晚上在不經意的情況下從電視上聽到了兩首歌,感覺還蠻好聽的,所以就分享給大家!

AKON -馬上就會好 right now
http://chen00139.pixnet.net/blog/post/24165694

王若琳(Joanna Wang) - Times of Your Life
http://yangxinde.pixnet.net/blog/post/24670590

星期二, 12月 23, 2008

SST SPI Serial Flash

今天在網路瀏覽的時候看到SST 有提供 Software Driver 的範例程式,從範例程式中可以很容易的知道如何
去控制Flash part的存取 , 如果想學R/W Flash Part的朋友可以參考看看,而底下是一個範例程式:

SST25VF080B 8 Mbit(1M x 8) Serial Flash Memory

November 4th, 2005, Rev. 1.0

ABOUT THE SOFTWARE
This application note provides software driver examples for SST25VF080B,
Serial Flash. Extensive comments are included in each routine to describe
the function of each routine. The interface coding uses polling method
rather than the SPI protocol to interface with these serial devices. The
functions are differentiated below in terms of the communication protocols
(uses Mode 0) and specific device operation instructions. This code has been
designed to compile using the Keil compiler.


ABOUT THE SST25VF080B

Companion product datasheets for the SST25VF080B should be reviewed in
conjunction with this application note for a complete understanding
of the device.


Device Communication Protocol(pinout related) functions:

Functions Function
------------------------------------------------------------------
init Initializes clock to set up mode 0.
Send_Byte Sends one byte using SI pin to send and
shift out 1-bit per clock rising edge
Get_Byte Receives one byte using SO pin to receive and shift
in 1-bit per clock falling edge
Poll_SO Used in the polling for RY/BY# of SO during AAI programming
CE_High Sets Chip Enable pin of the serial flash to high
CE_Low Clears Chip Enable of the serial flash to low
Hold_Low Clears Hold pin to make serial flash hold
Unhold Unholds the serial flash
WP_Low Clears WP pin to make serial flash write protected
UnWP Disables write protection pin

Note: The pin names of the SST25VF080B are used in this application note. The associated test code
will not compile unless these pinouts (SCK, SI, SO, SO, CE, WP, Hold) are pre-defined on your
software which should reflect your hardware interfaced.


Device Operation Instruction functions:

Functions Function
------------------------------------------------------------------
Read_Status_Register Reads the status register of the serial flash
EWSR Enables the Write Status Register
WRSR Performs a write to the status register
WREN Write enables the serial flash
WRDI Write disables the serial flash
EBSY Enable SO to output RY/BY# status during AAI programming
DBSY Disable SO to output RY/BY# status during AAI programming
Read_ID Reads the manufacturer ID and device ID
Jedec_ID_Read Reads the Jedec ID
Read Reads one byte from the serial flash and returns byte(max of 25 MHz CLK frequency)
Read_Cont Reads multiple bytes(max of 25 MHz CLK frequency)
HighSpeed_Read Reads one byte from the serial flash and returns byte(max of 50 MHz CLK frequency)
HighSpeed_Read_Cont Reads multiple bytes(max of 50 MHz CLK frequency)
Byte_Program Program one byte to the serial flash
Auto_Add_IncA Initial Auto Address Increment process
Auto_Add_IncB Successive Auto_Address_Increment process after AAI initiation
Auto_Add_IncA_EBSY Initial Auto Address Increment process with EBSY
Auto_Add_IncB_EBSY Successive Auto_Address_Increment process after AAI initiation with EBSY and WRDI/DBSY
Chip_Erase Erases entire serial flash
Sector_Erase Erases one sector (4 KB) of the serial flash
Block_Erase_32K Erases 32 KByte block memory of the serial flash
Block_Erase_64K Erases 64 KByte block memory of the serial flash
Wait_Busy Polls status register until busy bit is low
Wait_Busy_AAI Polls status register until busy bit is low for AAI programming
WREN_Check Checks to see if WEL is set
WREN_AAI_Check Checks to see if WEL and AAI mode is set




"C" LANGUAGE DRIVERS

/********************************************************************/
/* Copyright Silicon Storage Technology, Inc. (SST), 1994-2005 */
/* Example "C" language Driver of SST25VF080B Serial Flash */
/* Conrado Canio, Silicon Storage Technology, Inc. */
/* */
/* Revision 1.0, November 4th, 2005 */
/* */
/* */
/********************************************************************/

#include
#include

/* Function Prototypes */

void init();
void Send_Byte(unsigned char out);
unsigned char Get_Byte();
void Poll_SO();
void CE_High();
void CE_Low();
void Hold_Low();
void Unhold();
void WP_Low();
void UnWP();
unsigned char Read_Status_Register();
void EWSR();
void WRSR(byte);
void WREN();
void WRDI();
void EBSY();
void DBSY();
unsigned char Read_ID(ID_addr);
unsigned long Jedec_ID_Read();
unsigned char Read(unsigned long Dst);
void Read_Cont(unsigned long Dst, unsigned long no_bytes);
unsigned char HighSpeed_Read(unsigned long Dst);
void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes);
void Byte_Program(unsigned long Dst, unsigned char byte);
void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2);
void Auto_Add_IncB(unsigned char byte1, unsigned char byte2);
void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2);
void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2);
void Chip_Erase();
void Sector_Erase(unsigned long Dst);
void Block_Erase_32K(unsigned long Dst);
void Block_Erase_64K(unsigned long Dst);
void Wait_Busy();
void Wait_Busy_AAI();
void WREN_Check();
void WREN_AAI_Check();

void Verify(unsigned char byte, unsigned char cor_byte);

unsigned char idata upper_128[128]; /* global array to store read data */
/* to upper RAM area from 80H - FFH */

/************************************************************************/
/* PROCEDURE: init */
/* */
/* This procedure initializes the SCK to low. Must be called prior to */
/* setting up mode 0. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* SCK */
/************************************************************************/
void init()
{
SCK = 0; /* set clock to low initial state */
}

/************************************************************************/
/* PROCEDURE: Send_Byte */
/* */
/* This procedure outputs a byte shifting out 1-bit per clock rising */
/* edge on the the SI pin(LSB 1st). */
/* */
/* Input: */
/* out */
/* */
/* Output: */
/* SI */
/************************************************************************/
void Send_Byte(unsigned char out)
{

unsigned char i = 0;
for (i = 0; i < 8; i++)
{

if ((out & 0x80) == 0x80) /* check if MSB is high */
SI = 1;
else
SI = 0; /* if not, set to low */
SCK = 1; /* toggle clock high */
out = (out << 1); /* shift 1 place for next bit */
SCK = 0; /* toggle clock low */
}
}

/************************************************************************/
/* PROCEDURE: Get_Byte */
/* */
/* This procedure inputs a byte shifting in 1-bit per clock falling */
/* edge on the SO pin(LSB 1st). */
/* */
/* Input: */
/* SO */
/* */
/* Output: */
/* None */
/************************************************************************/
unsigned char Get_Byte()
{
unsigned char i = 0, in = 0, temp = 0;
for (i = 0; i < 8; i++)
{
in = (in << 1); /* shift 1 place to the left or shift in 0 */
temp = SO; /* save input */
SCK = 1; /* toggle clock high */
if (temp == 1) /* check to see if bit is high */
in = in | 0x01; /* if high, make bit high */

SCK = 0; /* toggle clock low */

}
return in;
}

/************************************************************************/
/* PROCEDURE: Poll_SO */
/* */
/* This procedure polls for the SO line during AAI programming */
/* waiting for SO to transition to 1 which will indicate AAI programming*/
/* is completed */
/* */
/* Input: */
/* SO */
/* */
/* Output: */
/* None */
/************************************************************************/
void Poll_SO()
{
unsigned char temp = 0;
CE_Low();
while (temp == 0x00) /* waste time until not busy */
temp = SO;
CE_High();
}

/************************************************************************/
/* PROCEDURE: CE_High */
/* */
/* This procedure set CE = High. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* CE */
/* */
/************************************************************************/
void CE_High()
{
CE = 1; /* set CE high */
}

/************************************************************************/
/* PROCEDURE: CE_Low */
/* */
/* This procedure drives the CE of the device to low. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* CE */
/* */
/************************************************************************/
void CE_Low()
{
CE = 0; /* clear CE low */
}

/************************************************************************/
/* PROCEDURE: Hold() */
/* */
/* This procedure clears the Hold pin to low. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* Hold */
/************************************************************************/
void Hold_Low()
{
Hold = 0; /* clear Hold pin */
}

/************************************************************************/
/* PROCEDURE: Unhold() */
/* */
/* This procedure sets the Hold pin to high. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* Hold */
/************************************************************************/
void Unhold()
{
Hold = 1; /* set Hold pin */
}

/************************************************************************/
/* PROCEDURE: WP() */
/* */
/* This procedure clears the WP pin to low. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* WP */
/************************************************************************/
void WP_Low()
{
WP = 0; /* clear WP pin */
}

/************************************************************************/
/* PROCEDURE: UnWP() */
/* */
/* This procedure sets the WP pin to high. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* WP */
/************************************************************************/
void UnWP()
{
WP = 1; /* set WP pin */
}

/************************************************************************/
/* PROCEDURE: Read_Status_Register */
/* */
/* This procedure read the status register and returns the byte. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* byte */
/************************************************************************/
unsigned char Read_Status_Register()
{
unsigned char byte = 0;
CE_Low(); /* enable device */
Send_Byte(0x05); /* send RDSR command */
byte = Get_Byte(); /* receive byte */
CE_High(); /* disable device */
return byte;
}

/************************************************************************/
/* PROCEDURE: EWSR */
/* */
/* This procedure Enables Write Status Register. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void EWSR()
{
CE_Low(); /* enable device */
Send_Byte(0x50); /* enable writing to the status register */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: WRSR */
/* */
/* This procedure writes a byte to the Status Register. */
/* */
/* Input: */
/* byte */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WRSR(byte)
{
CE_Low(); /* enable device */
Send_Byte(0x01); /* select write to status register */
Send_Byte(byte); /* data that will change the status of BPx
or BPL (only bits 2,3,4,5,7 can be written) */
CE_High(); /* disable the device */
}

/************************************************************************/
/* PROCEDURE: WREN */
/* */
/* This procedure enables the Write Enable Latch. It can also be used */
/* to Enables Write Status Register. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WREN()
{
CE_Low(); /* enable device */
Send_Byte(0x06); /* send WREN command */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: WRDI */
/* */
/* This procedure disables the Write Enable Latch. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WRDI()
{
CE_Low(); /* enable device */
Send_Byte(0x04); /* send WRDI command */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: EBSY */
/* */
/* This procedure enable SO to output RY/BY# status during AAI */
/* programming. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void EBSY()
{
CE_Low(); /* enable device */
Send_Byte(0x70); /* send EBSY command */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: DBSY */
/* */
/* This procedure disable SO as output RY/BY# status signal during AAI */
/* programming. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void DBSY()
{
CE_Low(); /* enable device */
Send_Byte(0x80); /* send DBSY command */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Read_ID */
/* */
/* This procedure Reads the manufacturer's ID and device ID. It will */
/* use 90h or ABh as the command to read the ID (90h in this sample). */
/* It is up to the user to give the last byte ID_addr to determine */
/* whether the device outputs manufacturer's ID first, or device ID */
/* first. Please see the product datasheet for details. Returns ID in */
/* variable byte. */
/* */
/* Input: */
/* ID_addr */
/* */
/* Returns: */
/* byte: ID1(Manufacture's ID = BFh or Device ID = 8Eh) */
/* */
/************************************************************************/
unsigned char Read_ID(ID_addr)
{
unsigned char byte;
CE_Low(); /* enable device */
Send_Byte(0x90); /* send read ID command (90h or ABh) */
Send_Byte(0x00); /* send address */
Send_Byte(0x00); /* send address */
Send_Byte(ID_addr); /* send address - either 00H or 01H */
byte = Get_Byte(); /* receive byte */
CE_High(); /* disable device */
return byte;
}

/************************************************************************/
/* PROCEDURE: Jedec_ID_Read */
/* */
/* This procedure Reads the manufacturer's ID (BFh), memory type (25h) */
/* and device ID (8Eh). It will use 9Fh as the JEDEC ID command. */
/* Please see the product datasheet for details. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* IDs_Read:ID1(Manufacture's ID = BFh, Memory Type (25h), */
/* and Device ID (8Eh) */
/* */
/************************************************************************/
unsigned long Jedec_ID_Read()
{
unsigned long temp;

temp = 0;

CE_Low(); /* enable device */
Send_Byte(0x9F); /* send JEDEC ID command (9Fh) */
temp = (temp | Get_Byte()) << 8; /* receive byte */
temp = (temp | Get_Byte()) << 8;
temp = (temp | Get_Byte()); /* temp value = 0xBF258E */
CE_High(); /* disable device */

return temp;
}

/************************************************************************/
/* PROCEDURE: Read */
/* */
/* This procedure reads one address of the device. It will return the */
/* byte read in variable byte. */
/* */
/* */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* */
/* Returns: */
/* byte */
/* */
/************************************************************************/
unsigned char Read(unsigned long Dst)
{
unsigned char byte = 0;

CE_Low(); /* enable device */
Send_Byte(0x03); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
byte = Get_Byte();
CE_High(); /* disable device */
return byte; /* return one byte read */
}

/************************************************************************/
/* PROCEDURE: Read_Cont */
/* */
/* This procedure reads multiple addresses of the device and stores */
/* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* no_bytes Number of bytes to read (max = 128) */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Read_Cont(unsigned long Dst, unsigned long no_bytes)
{
unsigned long i = 0;
CE_Low(); /* enable device */
Send_Byte(0x03); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
for (i = 0; i < no_bytes; i++) /* read until no_bytes is reached */
{
upper_128[i] = Get_Byte(); /* receive byte and store at address 80H - FFH */
}
CE_High(); /* disable device */

}

/************************************************************************/
/* PROCEDURE: HighSpeed_Read */
/* */
/* This procedure reads one address of the device. It will return the */
/* byte read in variable byte. */
/* */
/* */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* */
/* Returns: */
/* byte */
/* */
/************************************************************************/
unsigned char HighSpeed_Read(unsigned long Dst)
{
unsigned char byte = 0;

CE_Low(); /* enable device */
Send_Byte(0x0B); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(0xFF); /*dummy byte*/
byte = Get_Byte();
CE_High(); /* disable device */
return byte; /* return one byte read */
}

/************************************************************************/
/* PROCEDURE: HighSpeed_Read_Cont */
/* */
/* This procedure reads multiple addresses of the device and stores */
/* data into 128 byte buffer. Maximum byte that can be read is 128 bytes*/
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* no_bytes Number of bytes to read (max = 128) */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void HighSpeed_Read_Cont(unsigned long Dst, unsigned long no_bytes)
{
unsigned long i = 0;
CE_Low(); /* enable device */
Send_Byte(0x0B); /* read command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(0xFF); /*dummy byte*/
for (i = 0; i < no_bytes; i++) /* read until no_bytes is reached */
{
upper_128[i] = Get_Byte(); /* receive byte and store at address 80H - FFH */
}
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Byte_Program */
/* */
/* This procedure programs one address of the device. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* byte: byte to be programmed */
/* */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Byte_Program(unsigned long Dst, unsigned char byte)
{
CE_Low(); /* enable device */
Send_Byte(0x02); /* send Byte Program command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(byte); /* send byte to be programmed */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Auto_Add_IncA */
/* */
/* This procedure programs consecutive addresses of 2 bytes of data into*/
/* the device: 1st data byte will be programmed into the initial */
/* address [A23-A1] and with A0 = 0. The 2nd data byte will be be */
/* programmed into initial address [A23-A1] and with A0 = 1. This */
/* is used to to start the AAI process. It should be followed by */
/* Auto_Add_IncB. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* */
/* Note: Only RDSR command can be executed once in AAI mode with SO */
/* disable to output RY/BY# status. Use WRDI to exit AAI mode */
/* unless AAI is programming the last address or last address of */
/* unprotected block, which automatically exits AAI mode. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* byte1: 1st byte to be programmed */
/* byte1: 2nd byte to be programmed */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncA(unsigned long Dst, unsigned char byte1, unsigned char byte2)
{
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Auto_Add_IncB */
/* */
/* This procedure programs consecutive addresses of 2 bytes of data into*/
/* the device: 1st data byte will be programmed into the initial */
/* address [A23-A1] and with A0 = 0. The 2nd data byte will be be */
/* programmed into initial address [A23-A1] and with A0 = 1. This */
/* is used after Auto_Address_IncA. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* Note: Only WRDI and AAI command can be executed once in AAI mode */
/* with SO enabled as RY/BY# status. When the device is busy */
/* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
/* to exit AAI mode unless AAI is programming the last address or */
/* last address of unprotected block, which automatically exits */
/* AAI mode. */
/* */
/* Input: */
/* */
/* byte1: 1st byte to be programmed */
/* byte2: 2nd byte to be programmed */
/* */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncB(unsigned char byte1, unsigned char byte2)
{
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Auto_Add_IncA_EBSY */
/* */
/* This procedure is the same as procedure Auto_Add_IncA except that it */
/* uses EBSY and Poll_SO functions to check for RY/BY. It programs */
/* consecutive addresses of the device. The 1st data byte will be */
/* programmed into the initial address [A23-A1] and with A0 = 0. The */
/* 2nd data byte will be programmed into initial address [A23-A1] and */
/* with A0 = 1. This is used to to start the AAI process. It should */
/* be followed by Auto_Add_IncB_EBSY. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* */
/* Note: Only WRDI and AAI command can be executed once in AAI mode */
/* with SO enabled as RY/BY# status. When the device is busy */
/* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
/* to exit AAI mode unless AAI is programming the last address or */
/* last address of unprotected block, which automatically exits */
/* AAI mode. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* byte1: 1st byte to be programmed */
/* byte1: 2nd byte to be programmed */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncA_EBSY(unsigned long Dst, unsigned char byte1, unsigned char byte2)
{
EBSY(); /* enable RY/BY# status for SO in AAI */

CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */

Poll_SO(); /* polls RY/BY# using SO line */

}

/************************************************************************/
/* PROCEDURE: Auto_Add_IncB_EBSY */
/* */
/* This procedure is the same as Auto_Add_IncB except that it uses */
/* Poll_SO to poll for RY/BY#. It demonstrate on how to use DBSY after */
/* AAI programmming is completed. It programs consecutive addresses of */
/* the device. The 1st data byte will be programmed into the initial */
/* address [A23-A1] and with A0 = 0. The 2nd data byte will be */
/* programmed into initial address [A23-A1] and with A0 = 1. This is */
/* used after Auto_Address_IncA. */
/* Assumption: Address being programmed is already erased and is NOT */
/* block protected. */
/* */
/* Note: Only WRDI and AAI command can be executed once in AAI mode */
/* with SO enabled as RY/BY# status. When the device is busy, */
/* asserting CE# will output the status of RY/BY# on SO. Use WRDI */
/* to exit AAI mode unless AAI is programming the last address or */
/* last address of unprotected block, which automatically exits */
/* AAI mode. */
/* */
/* Input: */
/* */
/* byte1: 1st byte to be programmed */
/* byte2: 2nd byte to be programmed */
/* */
/* */
/* Returns: */
/* Nothing */
/* */
/************************************************************************/
void Auto_Add_IncB_EBSY(unsigned char byte1, unsigned char byte2)
{
CE_Low(); /* enable device */
Send_Byte(0xAD); /* send AAI command */
Send_Byte(byte1); /* send 1st byte to be programmed */
Send_Byte(byte2); /* send 2nd byte to be programmed */
CE_High(); /* disable device */

Poll_SO(); /* polls RY/BY# using SO line */

WRDI(); /* Exit AAI before executing DBSY */
DBSY(); /* disable SO as RY/BY# output if in AAI */
}

/************************************************************************/
/* PROCEDURE: Chip_Erase */
/* */
/* This procedure erases the entire Chip. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Chip_Erase()
{
CE_Low(); /* enable device */
Send_Byte(0x60); /* send Chip Erase command (60h or C7h) */
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Sector_Erase */
/* */
/* This procedure Sector Erases the Chip. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Sector_Erase(unsigned long Dst)
{


CE_Low(); /* enable device */
Send_Byte(0x20); /* send Sector Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Block_Erase_32K */
/* */
/* This procedure Block Erases 32 KByte of the Chip. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Block_Erase_32K(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0x52); /* send 32 KByte Block Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Block_Erase_64K */
/* */
/* This procedure Block Erases 64 KByte of the Chip. */
/* */
/* Input: */
/* Dst: Destination Address 000000H - 0FFFFFH */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Block_Erase_64K(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0xD8); /* send 64KByte Block Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}

/************************************************************************/
/* PROCEDURE: Wait_Busy */
/* */
/* This procedure waits until device is no longer busy (can be used by */
/* Byte-Program, Sector-Erase, Block-Erase, Chip-Erase). */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Wait_Busy()
{
while (Read_Status_Register() == 0x03) /* waste time until not busy */
Read_Status_Register();
}

/************************************************************************/
/* PROCEDURE: Wait_Busy_AAI */
/* */
/* This procedure waits until device is no longer busy for AAI mode. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Wait_Busy_AAI()
{
while (Read_Status_Register() == 0x43) /* waste time until not busy */
Read_Status_Register();
}

/************************************************************************/
/* PROCEDURE: WREN_Check */
/* */
/* This procedure checks to see if WEL bit set before program/erase. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WREN_Check()
{
unsigned char byte;
byte = Read_Status_Register(); /* read the status register */
if (byte != 0x02) /* verify that WEL bit is set */
{
while(1)
/* add source code or statements for this file */
/* to compile */
/* i.e. option: insert a display to view error on LED? */

}
}

/************************************************************************/
/* PROCEDURE: WREN_AAI_Check */
/* */
/* This procedure checks for AAI and WEL bit once in AAI mode. */
/* */
/* Input: */
/* None */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void WREN_AAI_Check()
{
unsigned char byte;
byte = Read_Status_Register(); /* read the status register */
if (byte != 0x42) /* verify that AAI and WEL bit is set */
{
while(1)
/* add source code or statements for this file */
/* to compile */
/* i.e. option: insert a display to view error on LED? */

}
}

/************************************************************************/
/* PROCEDURE: Verify */
/* */
/* This procedure checks to see if the correct byte has be read. */
/* */
/* Input: */
/* byte: byte read */
/* cor_byte: correct_byte that should be read */
/* */
/* Returns: */
/* Nothing */
/************************************************************************/
void Verify(unsigned char byte, unsigned char cor_byte)
{
if (byte != cor_byte)
{
while(1)
/* add source code or statement for this file */
/* to compile */
/* i.e. option: insert a display to view error on LED? */

}
}


int main()
{

return 0;
}

而範例程式中已經把主要的控制方式的"概念"都已經列出來了!
所以只要讀一下Datasheet應該就可以了解他的意義!

至於main()裡面要做甚麼就因人而異,因此千萬不要問我 main()要怎麼寫!

Reference
http://www.sst.com

點Software Driver 旁邊的TXT就可以看到範例程式

星期六, 12月 13, 2008

網友Joey的網站

今天收到一位網友Joey的來信,來信中分享了他的網站以及他的作品!

在瀏覽過他的網站與作品後,看到他對自己的作品有所堅持並且加入自己的巧思與創新,然後開發出不一樣感覺的工具! 真是深深的佩服他!

看到他這麼努力的研究,就更感覺自己太懶惰了! 以前為了寫程式廢寢忘食的我去了哪裡呢?!
我自己也要反省一下了>.<... 以下是他的作品之一的簡介,如果有興趣的朋友可以去他的網站下載:

Mini OSW 是全世界最小的多重開機程式,只有 396 Bytes,
如果你原本有使用其它的多重開機程式,
也可以很快的使用 MiniOSW 替代。
可說是,麻雀雖小,五臟俱全。


Joey 的網站:
http://chizone.miroko.tw/

星期日, 12月 07, 2008

MRT v.s Microsoft® Windows® 惡意軟體移除工具

MRT ?? 不是指我們的捷運 Metropolitan Rapid Transit(M.R.T 大都會捷運系統)!

一般如果你有安裝正版的Vista 或是XP , 而且有開啟自動更新功能時,你會發現他會自動下載一個叫做Microsoft® Windows® 惡意軟體移除工具的軟體! 當他安裝好之後你卻不曾看過他執行!

要如何使用微軟提供的這的工具呢?

很簡單,你只要到 開始->執行 ,然後鍵入"MRT"後按下確定,那麼這個工具就會被你叫出來執行了!