📄 嵌入式---程序示例4.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>设置中断向量表到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执行结束后,系统跳转执行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>跳转到LR中romStart()的地址,执行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>中断的产生和VxWorks系统的中断操作:</STRONG></P>
<DIV align=left>
<TABLE height=138 width=679 border=0>
<TBODY>
<TR>
<TD width=719 colSpan=2 height=76>一般中断的产生是由硬件定义的,如串口中断的定义:
<BR><BR>1.接收中断:当接收中断使能,接收数据存储器 RxData 存在有效数据,则产生中断.
<BR>2.发送中断:当发送中断使能,发送数据存储器 TxData 为空,则产生中断. <BR></TD></TR>
<TR>
<TD width=312>
<P align=center><IMG height=226 alt="zhongduanT.gif (2609 字节)"
src="嵌入式---程序示例4.files/zhongduanT.gif" width=290></P>
<P align=center>硬件发送中断产生逻辑示意</P></TD>
<TD width=376>
<P align=center><IMG height=226 alt="zhongduan.gif (2531 字节)"
src="嵌入式---程序示例4.files/zhongduan.gif" width=290></P>
<P align=center>硬件接收中断产生逻辑示意</P></TD></TR>
<TR>
<TD width=719 colSpan=2 height=37>
<P>所以要产生一个串口中断,主要有两步:
<BR><BR>1.使能这两个串口中断,RX Enable,TX Enable,函数intEnable().
<BR>2.用intConnect()登记中断号,和相应的中断例程ISR.
<BR></P></TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
<P><B> 程序示例</B></P>
<BLOCKQUOTE>
<BLOCKQUOTE>
<P align=left><B>在VxWorks系统上登记,使能串口中断</B></P></BLOCKQUOTE>
<BLOCKQUOTE>
<P align=left> intConnect((VOIDFUNCPTR *)5,ComISR,0);
//登记中断服务程序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
设置波特率<BR> *(unsigned long *)0x2000006c =
59; <BR></P>
<P align=left><B>//完成,
这样当串口有中断发生时,硬件系统会自动跳转到中断号5的地址0x18,调用程序ComISP().</B></P></BLOCKQUOTE></BLOCKQUOTE>
<BLOCKQUOTE>
<P
align=left><STRONG>注意:</STRONG>中断程序不能单步执行,或跟踪调试,中断服务程序中与函数库或系统有关的函数不可用如print()等,因为中断调用时,所有其它的任务都被挂起停止运行.</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系统的网络驱动(END)</STRONG></BIG></BIG></P>
<P><BIG>VxWorks网络配置参见</BIG><A
href="http://drew.nease.net/mypage/example/network_config.htm"><B>VxWorks网络驱动配置及分析</B></A></P>
<BLOCKQUOTE>
<P>
<BIG>VxWorks系统网络驱动在<STRONG>BSP</STRONG>中完成,写驱动时应参考<STRONG>BSP</STRONG> develop
kit,在VxWorks中叫做<STRONG>END</STRONG>( Enhanced Network
Driver),编写程序使用由VxWorks定义的<STRONG>MUX</STRONG>接口</BIG></P>
<P><BIG><STRONG>MUX</STRONG>是数据链路层和网络协议层之间的接口</BIG></P>
<P><BIG><STRONG>主要调用过程和步骤如下:</STRONG></BIG></P>
<P><BIG>VxWorks系统执行的第一个任务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)(该函数作用是添加<STRONG>MUX
END</STRONG>)<STRONG>========>></STRONG></BIG></P>
<P><BIG>pcooki = pCookie =
muxDevLoad(pDevTbl->unit,.....)其中pDevTbl在BSP网络配置文件configNet.h中定义.END_TBL_ENTRY
endDevTbl[]={...},该表定义了网络设备的具体参数,<STRONG>在这里调用了网络驱动</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()初始化系统为网络驱动运行做准备</P>
<P><STRONG>MUX</STRONG>调用ibmEmacStart()</P>
<P>ibmEmacStart() 登记中断服务程序ibmEmacInit(),启动设备运行在中断模式下.</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>中断服务程序ibmEmacInit() 处理EMAC控制器的中断,主要是 TX,RX状态错误</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网卡</STRONG></BIG></BIG>CS8900A
<BIG><BIG><STRONG>Linux驱动</STRONG></BIG></BIG></P>
<P>下面是我为一个网友解释的CS8900A网卡驱动文件中的部分函数,操作系统为<STRONG>ucLinux</STRONG>,CPU是国内常用的Motorola龙珠系列MC68EZ328(16M),相比PowerPC和ARM来说,它的结构简单,不带MMU,较易理解</P>
<P>CS8900A是一个16位网卡,支持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位的数组,分别赋值,16位寄存器是只有后8位可读写,<BR>//前8位是寄存器ID,所以这里吧后8位放在前面"_dest[0]=_src[1];"<BR>//然后通过I/O口,赋给相应的存储器,即"*(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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -