⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 嵌入式---程序示例4.htm

📁 bsp基本概念
💻 HTM
📖 第 1 页 / 共 3 页
字号:
    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)&nbsp; */<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 */&nbsp;&nbsp;&nbsp; <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> 
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mtlr p1 /* link register = C 
    entry point */ &nbsp;&nbsp;&nbsp; <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 */ 
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  </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.接收中断:当接收中断使能,接收数据存储器&nbsp;RxData&nbsp;存在有效数据,则产生中断. 
        <BR>2.发送中断:当发送中断使能,发送数据存储器&nbsp;TxData&nbsp;为空,则产生中断. <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&nbsp;Enable,TX&nbsp;Enable,函数intEnable(). 
        <BR>2.用intConnect()登记中断号,和相应的中断例程ISR. 
<BR></P></TD></TR></TBODY></TABLE></DIV></BLOCKQUOTE>
<P><B>&nbsp;&nbsp;&nbsp; 程序示例</B></P>
<BLOCKQUOTE>
  <BLOCKQUOTE>
    <P align=left><B>在VxWorks系统上登记,使能串口中断</B></P></BLOCKQUOTE>
  <BLOCKQUOTE>
    <P align=left>&nbsp;&nbsp;&nbsp; intConnect((VOIDFUNCPTR *)5,ComISR,0); 
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //登记中断服务程序ComISR()到外部中断号5,</P>
    <P align=left>&nbsp;&nbsp;&nbsp; intEnable((VOIDFUNCPTR *)5); 
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
    //使能外部中断5<BR><BR>&nbsp;&nbsp;&nbsp; <BR>//enable 使能 UART1 
    这里直接用32位地址表示了<BR>&nbsp;&nbsp;&nbsp; *(unsigned long *)0x20000014 &amp;= 
    ~0x01000100;&nbsp; //INT_FORCE &nbsp;&nbsp;&nbsp; use 
    pending<BR>&nbsp;&nbsp;&nbsp; *(unsigned long *)0x20000010 = 0x01000100; 
    &nbsp;&nbsp;&nbsp; //INT_PENDING&nbsp;&nbsp;&nbsp; 
    clear<BR>&nbsp;&nbsp;&nbsp; *(unsigned long *)0x20000018 = 
    0x01000100;&nbsp;&nbsp;&nbsp; //INT_MASK only enable UART1 
    RX<BR><BR><BR>//control register 使能 RX TX<BR>&nbsp;&nbsp;&nbsp; *(unsigned 
    long *)0x20000068 = 0x00070007;&nbsp;&nbsp;&nbsp; //RX and TX 
    ENABLE<BR><BR>//divider register,baut rate 19200&nbsp;&nbsp;&nbsp; 
    设置波特率<BR>&nbsp;&nbsp;&nbsp; *(unsigned long *)0x2000006c = 
    59;&nbsp;&nbsp;&nbsp; <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>&nbsp;&nbsp;&nbsp; </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>&nbsp;&nbsp;&nbsp; 
  <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>=======&gt;&gt;</STRONG></BIG></P>
  <P><BIG>target\src\config\usrNetwork.c文件(该文件初始化<STRONG>TCP/IP</STRONG>)中 
  usrNetInit(BOOT_LINE_ADRS)(该函数作用是添加<STRONG>MUX 
  END</STRONG>)<STRONG>========&gt;&gt;</STRONG></BIG></P>
  <P><BIG>pcooki = pCookie = 
  muxDevLoad(pDevTbl-&gt;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>========&gt;&gt;</STRONG>muxDevStart(pcooki)<STRONG>==========&gt;&gt;</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, 
    &amp;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-&gt;txChn0MalChannel,<BR>MAL_EOB_INT_EN | MAL_DE_INT_EN | 
    MAL_SERR_INT_EN);<BR><BR>malChannelIntMaskSet(MAL_RX_TYPE, 
    pDrvCtrl-&gt;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-&gt;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 &amp; 
    EMAC_ISR_TX_INTS)<BR>{<BR>pDrvCtrl-&gt;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 &amp; 
    EMAC_ISR_RX_INTS)<BR>{<BR>pDrvCtrl-&gt;intErrorRX++;<BR>SYS_OUT_LONG(pDrvCtrl, 
    EMAC_ISR, 
EMAC_ISR_RX_INTS);<BR>}<BR><BR>return;<BR>}</P></BLOCKQUOTE></BLOCKQUOTE>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<STRONG>(未完)</STRONG> &nbsp;&nbsp;&nbsp;&nbsp; </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>{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
  <BR>unsigned short newvalue; <BR>unsigned char *_src=(unsigned 
  char*)(&amp;value),*_dest=(unsigned 
  char*)(&amp;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];&nbsp;&nbsp;&nbsp; 
  <BR>_dest[1]=_src[0];&nbsp;&nbsp;&nbsp; <BR>*(volatile unsigned 
  short*)addr=newvalue;<BR>}</P>
  <P>static int cs89x0_probe1(struct device *dev, int 
  ioaddr)<BR>{<BR>&nbsp;&nbsp;&nbsp; struct net_local *lp;<BR>&nbsp;&nbsp;&nbsp; 
  static unsigned version_printed = 0;<BR>&nbsp;&nbsp;&nbsp; int 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -