?? 嵌入式---程序示例1.htm
字號:
bit<BR>*/<BR><BR>li r0, 0<BR>lwarx p0, r0, r0<BR>stwcx. p0, r0,
r0<BR><BR>#ifdef PPC405GP_REVA<BR>/* <STRONG>設(shè)置中斷向量表到0x0000</STRONG>
*/<BR>li p0, 0x2100/4<BR>mtctr p0<BR>lis p0, WALNUT_EVPR_VAL<BR>li p1,
0x0000<BR>zeroOut:<BR>stw p1,0x0(p0)<BR>addi p0, p0, 4<BR>bdnz
zeroOut<BR>#endif</P>
<P><BR><STRONG>/* 初始化堆棧</STRONG><BR>/* Initialize the stack pointer
(r1) */<BR><BR>lis sp, HIADJ(STACK_ADRS)<BR>addi sp, sp,
LO(STACK_ADRS)<BR><BR>#if FALSE /* SDA not supported */<BR>/* initialize r2
and r13 according to EABI standard */<BR><BR>lis r2,
HIADJ(_SDA2_BASE_)<BR>addi r2, r2, LO(_SDA2_BASE_)<BR>lis r13,
HIADJ(_SDA_BASE_)<BR>addi r13, r13, LO(_SDA_BASE_)<BR>#endif<BR><BR>/*
<STRONG>得到C程序romStart()在ROM中的地址,保證romInit執(zhí)行結(jié)束后,系統(tǒng)跳轉(zhuǎn)執(zhí)行romStart()</STRONG></P>
<P>/* calculate C entry point: routine - entry point + ROM base
*/<BR><BR>lis p1, HIADJ(romStart) /* p1 = romstart */<BR>addi p1, p1,
LO(romStart)<BR><BR>lis p2, HIADJ(romInit) /* p2 = romInit */<BR>addi p2,
p2, LO(romInit)<BR></P>
<P>/*
<STRONG>ROM_TEXT_ADRS為ROM的入口地址,在文件makefile定義,為0xfff80100</STRONG><BR>lis p3,
HIADJ(ROM_TEXT_ADRS) /* p3 = ROM_TEXT_ADRS */ <BR>addi p3,
p3, LO(ROM_TEXT_ADRS)<BR><BR>subf p1, p2, p1 /* p1 = p1 - p2 */<BR>add p1,
p1, p3 /* p1 = p1 + p3 */<BR>/*
<STRONG>p1中是romStart()的地址,這里把這個地址放到連接寄存器LR中.</STRONG>
mtlr p1 /* link register = C
entry point */ <BR><BR>or p0, p5, p5 /* p0 = startType
*/<BR>addi sp, sp, -FRAMEBASESZ /* get frame stack */<BR></P>
<P>/* <STRONG>跳轉(zhuǎn)到LR中romStart()的地址,執(zhí)行romStart()</STRONG><BR>blr /* branch to
link register */
</P></BLOCKQUOTE></BLOCKQUOTE>
<P> </P>
<P align=center><A
href="http://drew.nease.net/mypage/sourcecode.htm#returntop"><B>返回頁首</B></A></P>
<P align=center> </P>
<P><A name=INT></A><FONT color=black size=5><B>硬件中斷</B></FONT></P>
<BLOCKQUOTE>
<P><STRONG>中斷的產(chǎn)生和VxWorks系統(tǒng)的中斷操作:</STRONG></P>
<DIV align=left>
<TABLE height=138 width=679 border=0>
<TBODY>
<TR>
<TD width=719 colSpan=2 height=76>一般中斷的產(chǎn)生是由硬件定義的,如串口中斷的定義:
<BR><BR>1.接收中斷:當(dāng)接收中斷使能,接收數(shù)據(jù)存儲器 RxData 存在有效數(shù)據(jù),則產(chǎn)生中斷.
<BR>2.發(fā)送中斷:當(dāng)發(fā)送中斷使能,發(fā)送數(shù)據(jù)存儲器 TxData 為空,則產(chǎn)生中斷. <BR></TD></TR>
<TR>
<TD width=312>
<P align=center><IMG height=226 alt="zhongduanT.gif (2609 字節(jié))"
src="嵌入式---程序示例1.files/zhongduanT.gif" width=290></P>
<P align=center>硬件發(fā)送中斷產(chǎn)生邏輯示意</P></TD>
<TD width=376>
<P align=center><IMG height=226 alt="zhongduan.gif (2531 字節(jié))"
src="嵌入式---程序示例1.files/zhongduan.gif" width=290></P>
<P align=center>硬件接收中斷產(chǎn)生邏輯示意</P></TD></TR>
<TR>
<TD width=719 colSpan=2 height=37>
<P>所以要產(chǎn)生一個串口中斷,主要有兩步:
<BR><BR>1.使能這兩個串口中斷,RX Enable,TX Enable,函數(shù)intEnable().
<BR>2.用intConnect()登記中斷號,和相應(yīng)的中斷例程ISR.
<BR></P></TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
<P><B> 程序示例</B></P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P align=left><B>在VxWorks系統(tǒng)上登記,使能串口中斷</B></P></BLOCKQUOTE>
<BLOCKQUOTE>
<P align=left> intConnect((VOIDFUNCPTR *)5,ComISR,0);
//登記中斷服務(wù)程序ComISR()到外部中斷號5,</P>
<P align=left> intEnable((VOIDFUNCPTR *)5);
//使能外部中斷5<BR><BR> <BR>//enable 使能 UART1
這里直接用32位地址表示了<BR> *(unsigned long *)0x20000014 &=
~0x01000100; //INT_FORCE use
pending<BR> *(unsigned long *)0x20000010 = 0x01000100;
//INT_PENDING
clear<BR> *(unsigned long *)0x20000018 =
0x01000100; //INT_MASK only enable UART1
RX<BR><BR><BR>//control register 使能 RX TX<BR> *(unsigned
long *)0x20000068 = 0x00070007; //RX and TX
ENABLE<BR><BR>//divider register,baut rate 19200
設(shè)置波特率<BR> *(unsigned long *)0x2000006c =
59; <BR></P>
<P align=left><B>//完成,
這樣當(dāng)串口有中斷發(fā)生時,硬件系統(tǒng)會自動跳轉(zhuǎn)到中斷號5的地址0x18,調(diào)用程序ComISP().</B></P></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<P
align=left><STRONG>注意:</STRONG>中斷程序不能單步執(zhí)行,或跟蹤調(diào)試,中斷服務(wù)程序中與函數(shù)庫或系統(tǒng)有關(guān)的函數(shù)不可用如print()等,因為中斷調(diào)用時,所有其它的任務(wù)都被掛起停止運(yùn)行.</P></BLOCKQUOTE>
<P align=left><STRONG> </STRONG></P>
<P align=center><A
href="http://drew.nease.net/mypage/sourcecode.htm#returntop"><B>返回頁首</B></A></P>
<P> </P>
<P><BIG><A name=FLASH></A><A
name=NIC></A><BIG><STRONG>VxWorks系統(tǒng)的網(wǎng)絡(luò)驅(qū)動(END)</STRONG></BIG></BIG></P>
<P><BIG>VxWorks網(wǎng)絡(luò)配置參見</BIG><A
href="http://drew.nease.net/mypage/example/network_config.htm"><B>VxWorks網(wǎng)絡(luò)驅(qū)動配置及分析</B></A></P>
<BLOCKQUOTE>
<P>
<BIG>VxWorks系統(tǒng)網(wǎng)絡(luò)驅(qū)動在<STRONG>BSP</STRONG>中完成,寫驅(qū)動時應(yīng)參考<STRONG>BSP</STRONG> develop
kit,在VxWorks中叫做<STRONG>END</STRONG>( Enhanced Network
Driver),編寫程序使用由VxWorks定義的<STRONG>MUX</STRONG>接口</BIG></P>
<P><BIG><STRONG>MUX</STRONG>是數(shù)據(jù)鏈路層和網(wǎng)絡(luò)協(xié)議層之間的接口</BIG></P>
<P><BIG><STRONG>主要調(diào)用過程和步驟如下:</STRONG></BIG></P>
<P><BIG>VxWorks系統(tǒng)執(zhí)行的第一個任務(wù)target\config\all\usrConfig.c文件中
usrRoot()<STRONG>=======>></STRONG></BIG></P>
<P><BIG>target\src\config\usrNetwork.c文件(該文件初始化<STRONG>TCP/IP</STRONG>)中
usrNetInit(BOOT_LINE_ADRS)(該函數(shù)作用是添加<STRONG>MUX
END</STRONG>)<STRONG>========>></STRONG></BIG></P>
<P><BIG>pcooki = pCookie =
muxDevLoad(pDevTbl->unit,.....)其中pDevTbl在BSP網(wǎng)絡(luò)配置文件configNet.h中定義.END_TBL_ENTRY
endDevTbl[]={...},該表定義了網(wǎng)絡(luò)設(shè)備的具體參數(shù),<STRONG>在這里調(diào)用了網(wǎng)絡(luò)驅(qū)動</STRONG></BIG></P>
<P>END_TBL_ENTRY endDevTbl [] =<BR>{<BR>{0, IBM_EMAC_LOAD_FUNC,
IBM_EMAC_LOAD_STR_0, TRUE, NULL, FALSE},<BR>{0, END_TBL_END, NULL, 0, NULL,
FALSE},<BR>};<BR>其中<STRONG>IBM_EMAC_LOAD_FUNC</STRONG>就是 ibmEmacEndLoad()</P>
<P><STRONG>========>></STRONG>muxDevStart(pcooki)<STRONG>==========>></STRONG>ibmEmacEndLoad()</P>
<P> </P>
<P>ibmEmacEndLoad()初始化系統(tǒng)為網(wǎng)絡(luò)驅(qū)動運(yùn)行做準(zhǔn)備</P>
<P><STRONG>MUX</STRONG>調(diào)用ibmEmacStart()</P>
<P>ibmEmacStart() 登記中斷服務(wù)程序ibmEmacInit(),啟動設(shè)備運(yùn)行在中斷模式下.</P></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>LOCAL STATUS ibmEmacStart ( EMAC_DRV_CTRL * pDrvCtrl )<BR>{<BR>int
rc;<BR><BR>SYS_INT_CONNECT (pDrvCtrl, ibmEmacInt, pDrvCtrl,
&rc);<BR>SYS_OUT_LONG(pDrvCtrl, EMAC_ISR, 0xFFFFFFFF);<BR>SYS_INT_ENABLE
();<BR><BR>/* Allow MAL EOB and Descriptor error interrupts
*/<BR><BR>malChannelIntMaskSet(MAL_TX_TYPE,
pDrvCtrl->txChn0MalChannel,<BR>MAL_EOB_INT_EN | MAL_DE_INT_EN |
MAL_SERR_INT_EN);<BR><BR>malChannelIntMaskSet(MAL_RX_TYPE,
pDrvCtrl->rxChn0MalChannel,<BR>MAL_EOB_INT_EN | MAL_DE_INT_EN |
MAL_SERR_INT_EN);<BR><BR>return (OK);<BR>}</P></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<P>中斷服務(wù)程序ibmEmacInit() 處理EMAC控制器的中斷,主要是 TX,RX狀態(tài)錯誤</P></BLOCKQUOTE>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P>LOCAL void ibmEmacInt ( EMAC_DRV_CTRL * pDrvCtrl )<BR>{<BR>UINT
isrReg;<BR><BR>/* Read the EMAC interrupt status register
*/<BR><BR>SYS_IN_LONG(pDrvCtrl, EMAC_ISR, isrReg);<BR>pDrvCtrl->errorEmac
= isrReg;<BR><BR>/*<BR>* Check to see if there was a TX error. If there was,
the Dead bit<BR>* will be set. Clear the status bits for the TX error, and
clear the dead<BR>* bit. Keep count of these errors in the main device
structure.<BR>*/<BR><BR>if (isrReg &
EMAC_ISR_TX_INTS)<BR>{<BR>pDrvCtrl->intErrorTX++;<BR>SYS_OUT_LONG(pDrvCtrl,
EMAC_ISR, EMAC_ISR_TX_INTS);<BR>}<BR><BR>/*<BR>* Check to see if there was a
RX error. Clear the status bits for the RX<BR>* error. Keep count of these
errors in the main device structure.<BR>*/<BR><BR>if (isrReg &
EMAC_ISR_RX_INTS)<BR>{<BR>pDrvCtrl->intErrorRX++;<BR>SYS_OUT_LONG(pDrvCtrl,
EMAC_ISR,
EMAC_ISR_RX_INTS);<BR>}<BR><BR>return;<BR>}</P></BLOCKQUOTE></BLOCKQUOTE>
<P>
<STRONG>(未完)</STRONG> </P>
<P> </P>
<P><BIG><BIG><STRONG>Cillus網(wǎng)卡</STRONG></BIG></BIG>CS8900A
<BIG><BIG><STRONG>Linux驅(qū)動</STRONG></BIG></BIG></P>
<P>下面是我為一個網(wǎng)友解釋的CS8900A網(wǎng)卡驅(qū)動文件中的部分函數(shù),操作系統(tǒng)為<STRONG>ucLinux</STRONG>,CPU是國內(nèi)常用的Motorola龍珠系列MC68EZ328(16M),相比PowerPC和ARM來說,它的結(jié)構(gòu)簡單,不帶MMU,較易理解</P>
<P>CS8900A是一個16位網(wǎng)卡,支持ISA總線,10-BastT.</P>
<BLOCKQUOTE>
<P>static inline void outw(unsigned short value,unsigned int addr)
<BR>{
<BR>unsigned short newvalue; <BR>unsigned char *_src=(unsigned
char*)(&value),*_dest=(unsigned
char*)(&newvalue);<BR><BR>//這里為什么要交換一下?<BR><BR>////++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<BR>//這里不是交換,而是賦值,將16位分成兩個8位的數(shù)組,分別賦值,16位寄存器是只有后8位可讀寫,<BR>//前8位是寄存器ID,所以這里吧后8位放在前面"_dest[0]=_src[1];"<BR>//然后通過I/O口,賦給相應(yīng)的存儲器,即"*(volatile
unsigned
short*)addr=newvalue;"<BR>///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
<BR><BR>_dest[0]=_src[1];
<BR>_dest[1]=_src[0]; <BR>*(volatile unsigned
short*)addr=newvalue;<BR>}</P>
<P>static int cs89x0_probe1(struct device *dev, int
ioaddr)<BR>{<BR> struct net_local *lp;<BR>
static unsigned version_printed = 0;<BR> int
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -