UIP移植到CC2530上

2024-05-28 12:38
文章标签 移植 cc2530 uip

本文主要是介绍UIP移植到CC2530上,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近老板有个项目,其中要做一个Zigbee的无线接入点,即将ZigBee无线传感网络中的数据通过TCP/IP协议传输到以太网上。传统的这种无线接入点即网关都是上位机加下位机模式做成的,即主控芯片(如ARM)加无线模块(如cc2530),ARM与cc2530通过UARST通信,cc2530建立WSN网络,ARM与PC机通过TCP/IP通信,考虑到此系统的成本以及其中的数据传输量不大,就不用ARM,直接将cc2530做成网关,这就需要将TCP/IP协议栈移植到cc2530上,同时与ZigBee协议栈能很好的协同运行。

       因为cc2530的FLASH有256K,Z-stack占用了大部分,所以要用TCP/IP,只能移植一个轻量型网络协议栈,现在比较流行的就是Adam Dunkels写的lwIP和uIP,还有Micrium的uc/IP,lwip和uc/ip所占空间较大,移植较为麻烦,所以就用uip。uip是一种免费可的极小的TCP/IP协议栈,主要实现了ARP,ICMP,TCP,UDP协议,在8位或16位单片机上用的较多,对rom和ram要求很少。

       在网上看了一些uip移植到51或STM32的文章,同时也花了两天时间看了uip的实现源码,如果不熟悉TCP/IP协议的话读起来还是很吃力,所以先看看TCP/IP,建议看TCP/IP协议详解——卷一。看完之后大概知道移植过程了。

       移植之前先要写网络芯片驱动程序,我用的是enc28j60,独立控制的SPI接口,因为cc2530的spi接口用来下载调试了,另一个spi被串口复用了,所以只用用GPIO模拟SPI。

      写驱动程序之前认真读了enc28j60的datasheet,在网上也找到了相关的驱动程序,可以稍加修改拿来用。下面贴出spi程序和enc28j60的程序。

 

[cpp]  view plain copy
  1. <span style="font-size:18px;">#include "spi.h"  
  2.   
  3. void WriteByte(u8_t dat)  
  4. {  
  5.   u8_t i;  
  6.   for(i=0;i<8;i++)  
  7.   {  
  8.     SCKN = 0;  
  9.     asm("nop");  
  10.     if(dat&0x80)  
  11.     {  
  12.        SIN = 1;  
  13.     }  
  14.     else   
  15.        SIN = 0;  
  16.     dat <<= 1;  
  17.     asm("nop");  
  18.     SCKN = 1;  
  19.     asm("nop");  
  20.   }  
  21.   SCKN=0; //空闲状态为低电平  
  22. }  
  23.   
  24. u8_t ReadByte(void)  
  25. {  
  26.   u8_t i,dat;  
  27.   SCKN=0;  
  28.   dat1=0;  
  29.   for(i=0;i<8;i++)  
  30.   {   
  31.     SCKN=1;  
  32.     dat1 <<=1;  
  33.     dat1 |= SON;   
  34.     SCKN=0;   
  35.   }  
  36.   return dat;  
  37. }  
  38. </span>  

 

     spi.h文件定义了与enc28j60spi接口的GPIO,

       

[cpp]  view plain copy
  1. <span style="font-size:18px;">#ifndef SPI_H  
  2. #define SPI_H  
  3. #include <ioCC2530.h>  
  4.   
  5. #define SON   P0_5    // MISO  
  6. #define SIN   P0_6    // MOSI  
  7. #define SCKN  P0_7    // SCK  
  8. #define CSN   P1_3    // 28J60-- CS  
  9. #define RESET P1_2    // Reset   
  10.   
  11. void WriteByte(u8_t dat);  
  12. u8_t ReadByte(void);  
  13.   
  14. #endif  
  15. </span>  



 

        enc28j60.c文件:

[cpp]  view plain copy
  1. <span style="font-size:18px;">#include "enc28j60.h"  
  2. #include "spi.h"  
  3.   
  4. #define MIN(a,b) (a) < (b) ? (a) : (b)  
  5. XDATA u8_t Enc28j60Bank;  
  6. XDATA u16_t NextPacketPtr;  
  7.   
  8. void delay_100ns()  
  9. {  
  10.      asm("nop");  
  11.      asm("nop");  
  12.      asm("nop");  
  13. }  
  14.   
  15. void delay_ms(int t1)  
  16. {   
  17.      int i;   
  18.      while(t1--)   
  19.      {  
  20.     for(i=10;i;--i)  
  21.         {  
  22.            delay_100ns();  
  23.         }  
  24.      }   
  25. }  
  26.   
  27. //*******************************************************************************************  
  28. //  
  29. // Function : enc28j60ReadOp  
  30. // Description :   
  31. //  
  32. //*******************************************************************************************  
  33. u8_t enc28j60ReadOp(u8_t op, u8_t address)  
  34. {  
  35.     u8_t dat1;  
  36.     // activate CS    
  37.     CSN =0;  
  38.     // issue read command  
  39.     delay_100ns();  
  40.     WriteByte(op | (address & ADDR_MASK));    
  41.     dat1 = ReadByte();  
  42.     // do dummy read if needed (for mac and mii, see datasheet page 29)  
  43.     if(address & 0x80)  dat1 = ReadByte();  
  44.     // release CS  
  45.     CSN=1;  
  46.     return(dat1);  
  47. }  
  48. //*******************************************************************************************  
  49. //  
  50. // Function : enc28j60WriteOp  
  51. // Description :   
  52. //  
  53. //*******************************************************************************************  
  54. void enc28j60WriteOp(u8_t op, u8_t address, u8_t mydat)  
  55. {  
  56.     CSN=0;  
  57.     // issue write command  
  58.     delay_100ns();  
  59.     WriteByte( op | (address & ADDR_MASK));  
  60.     // write data  
  61.     WriteByte(mydat);  
  62.     CSN=1;  
  63.     delay_100ns();  
  64. }  
  65. //*******************************************************************************************  
  66. //  
  67. // Function : icmp_send_request  
  68. // Description : Send ARP request packet to destination.  
  69. //  
  70. //*******************************************************************************************  
  71. void enc28j60SetBank(u8_t address)  
  72. {  
  73.     // set the bank (if needed)  
  74.     if((address & BANK_MASK) != Enc28j60Bank)  
  75.     {  
  76.         // set the bank  
  77.         enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1|ECON1_BSEL0));  
  78.         enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK)>>5);  
  79.         Enc28j60Bank = (address & BANK_MASK);  
  80.     }  
  81. }  
  82. //*******************************************************************************************  
  83. //  
  84. // Function : icmp_send_request  
  85. // Description : Send ARP request packet to destination.  
  86. //  
  87. //*******************************************************************************************  
  88. u8_t enc28j60Read(u8_t address)  
  89. {  
  90.     // select bank to read  
  91.     enc28j60SetBank(address);     
  92.     // do the read  
  93.     return enc28j60ReadOp(ENC28J60_READ_CTRL_REG, address);  
  94. }  
  95. //*******************************************************************************************  
  96. //  
  97. // Function : icmp_send_request  
  98. // Description : Send ARP request packet to destination.  
  99. //  
  100. //*******************************************************************************************  
  101. void enc28j60Write(u8_t address, u8_t mydat)  
  102. {  
  103.     // select bank to write  
  104.     enc28j60SetBank(address);   
  105.     // do the write  
  106.     enc28j60WriteOp(ENC28J60_WRITE_CTRL_REG, address, mydat);  
  107. }  
  108. //*******************************************************************************************  
  109. //  
  110. // Function : icmp_send_request  
  111. // Description : Send ARP request packet to destination.  
  112. //  
  113. //*******************************************************************************************  
  114. u16_t enc28j60_read_phyreg(u8_t address)  
  115. {  
  116.     u16_t mydat;  
  117.     // set the PHY register address  
  118.     enc28j60Write(MIREGADR, address);  
  119.     enc28j60Write(MICMD, MICMD_MIIRD);  
  120.     // Loop to wait until the PHY register has been read through the MII  
  121.     // This requires 10.24us  
  122.     while( (enc28j60Read(MISTAT) & MISTAT_BUSY) );  
  123.       
  124.     // Stop reading 这里应该清零  
  125.     //enc28j60Write(MICMD, MICMD_MIIRD);  
  126.     enc28j60Write(MICMD, 0x0);  
  127.     // Obtain results and return  
  128.     mydat = enc28j60Read ( MIRDL );  
  129.     //PrintHex(mydat);  
  130.     //mydat |= enc28j60Read ( MIRDH ); //此地方源代码有误 改成  
  131.     mydat |= (enc28j60Read ( MIRDH )<<8);  
  132.    // PrintHex(mydat);  
  133.     return mydat;  
  134. }   
  135. //*******************************************************************************************  
  136. //  
  137. // Function : icmp_send_request  
  138. // Description : Send ARP request packet to destination.  
  139. //  
  140. //*******************************************************************************************  
  141. void enc28j60PhyWrite(u8_t address, u16_t mydat)  
  142. {  
  143.     // set the PHY register address  
  144.     enc28j60Write(MIREGADR, address);  
  145.     // write the PHY data  
  146.     enc28j60Write(MIWRL, mydat & 0x00ff);  
  147.     enc28j60Write(MIWRH, mydat >> 8);  
  148.     // wait until the PHY write completes  
  149.     while(enc28j60Read(MISTAT) & MISTAT_BUSY)  
  150.     {  
  151.             delay_100ns();  
  152.     }  
  153. }  
  154.   
  155. void enc28j60ReadBuffer(u16_t len, u8_t* dat)  
  156. {  
  157.     // assert CS  
  158.     CSN = 0;  
  159.     // issue read command  
  160.     delay_100ns();  
  161.     WriteByte(ENC28J60_READ_BUF_MEM);           
  162.     while(len--)  
  163.     {  
  164.        *dat++ = ReadByte();  
  165.     }     
  166.     // release CS  
  167.     CSN = 1;  
  168. }  
  169.   
  170. void enc28j60WriteBuffer(u16_t len, u8_t* dat)  
  171. {  
  172.     // assert CS  
  173.     CSN = 0;   
  174.     // issue write command   
  175.     WriteByte(ENC28J60_WRITE_BUF_MEM);  
  176.     // while(!(SPSR & (1<<SPIF)));  
  177.     while(len--)  
  178.     {        
  179.        WriteByte(*dat++);  
  180.     }     
  181.     // release CS  
  182.     CSN = 1;  
  183. }  
  184.   
  185. #define ETHERNET_MIN_PACKET_LENGTH  0x3C  
  186. #define ETHERNET_HEADER_LENGTH      0x0E  
  187. #define IP_TCP_HEADER_LENGTH 40  
  188. #define TOTAL_HEADER_LENGTH (IP_TCP_HEADER_LENGTH+ETHERNET_HEADER_LENGTH)  
  189.   
  190. void enc28j60PacketSend(u16_t len, u8_t* packet)  
  191. {  
  192.     // Set the write pointer to start of transmit buffer area  
  193.     enc28j60Write(EWRPTL, TXSTART_INIT);  
  194.     enc28j60Write(EWRPTH, TXSTART_INIT>>8);  
  195.     // Set the TXND pointer to correspond to the packet size given  
  196.     enc28j60Write(ETXNDL, (TXSTART_INIT+len));  
  197.     enc28j60Write(ETXNDH, (TXSTART_INIT+len)>>8);  
  198.     // write per-packet control byte  
  199.     enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);  
  200.     // TODO, fix this up  
  201.     if( uip_len <= TOTAL_HEADER_LENGTH )  
  202.     {  
  203.         // copy the packet into the transmit buffer  
  204.         enc28j60WriteBuffer(len, packet);  
  205.     }  
  206.     else  
  207.     {  
  208.         len -= TOTAL_HEADER_LENGTH;  
  209.         enc28j60WriteBuffer(TOTAL_HEADER_LENGTH, packet);  
  210.         enc28j60WriteBuffer(len, (unsigned char *)uip_appdata);  
  211.     }  
  212.     // send the contents of the transmit buffer onto the network  
  213.     enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);  
  214. }  
  215.   
  216. u16_t enc28j60PacketReceive(u16_t maxlen, u8_t* packet)  
  217. {  
  218.     u16_t rxstat,len;  
  219.     if (enc28j60Read(EPKTCNT) == 0)  
  220.     {   
  221.       return 0;  
  222.     }  
  223. // Set the read pointer to the start of the received packet  
  224.     enc28j60Write(ERDPTL, (NextPacketPtr));  
  225.     enc28j60Write(ERDPTH, (NextPacketPtr)>>8);  
  226. // read the next packet pointer  
  227.     NextPacketPtr  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);  
  228.     NextPacketPtr |= (enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8);       
  229. // read the packet length  
  230.     len  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);  
  231.     len |= (enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8);  
  232.     len -= 4; //以太帧最小46字节 减去4字节的FCS校验和 加上帧头14字节 共64字节  
  233.  //PrintHex(len);  
  234. // read the receive status  
  235.     rxstat  = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);  
  236.     rxstat |= enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0)<<8;  
  237. // limit retrieve length  
  238.     // (we reduce the MAC-reported length by 4 to remove the CRC)  
  239.     len = MIN(len, maxlen);  
  240. // copy the packet from the receive buffer  
  241.     enc28j60ReadBuffer(len, packet);  
  242. // Errata workaround #13. Make sure ERXRDPT is odd  
  243.     u16_t rs,re;  
  244.     rs = enc28j60Read(ERXSTH);  
  245.     rs <<= 8;  
  246.     rs |= enc28j60Read(ERXSTL);  
  247.     re = enc28j60Read(ERXNDH);  
  248.     re <<= 8;  
  249.     re |= enc28j60Read(ERXNDL);  
  250.     if (NextPacketPtr - 1 < rs || NextPacketPtr - 1 > re)  
  251.     {  
  252.         enc28j60Write(ERXRDPTL, (re));  
  253.         enc28j60Write(ERXRDPTH, (re)>>8);  
  254.     }  
  255.     else  
  256.     {  
  257.         enc28j60Write(ERXRDPTL, (NextPacketPtr-1));  
  258.         enc28j60Write(ERXRDPTH, (NextPacketPtr-1)>>8);  
  259.     }  
  260. // decrement the packet counter indicate we are done with this packet  
  261.     enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);         
  262.     return len;  
  263. }  
  264.   
  265. void dev_init(void)  
  266. {  
  267.     enc28j60_init();  
  268. }  
  269.   
  270. void dev_send(void)  
  271. {  
  272.     enc28j60PacketSend(uip_len, uip_buf);  
  273. }  
  274.   
  275. u16_t dev_poll(void)  
  276. {  
  277.     return enc28j60PacketReceive(UIP_BUFSIZE, uip_buf);  
  278. }  
  279.   
  280. void enc28j60_init(void)  
  281. {  
  282. //SPI INIT  
  283.     SpiInit();      
  284. // perform system reset  
  285.     enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);  
  286. // check CLKRDY bit to see if reset is complete  
  287.     //while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));  
  288.     // Errata workaround #2, CLKRDY check is unreliable, delay 1 mS instead  
  289.     delay_ms(5);  
  290. // lamp test  
  291. // enc28j60PhyWrite(PHLCON, 0x0AA2);  
  292.       
  293. // do bank 0 stuff  
  294.     // initialize receive buffer  
  295.     // 16-bit transfers, must write low byte first  
  296. // set receive buffer start address  
  297.     NextPacketPtr = RXSTART_INIT;  
  298.     enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);  
  299.     enc28j60Write(ERXSTH, RXSTART_INIT>>8);  
  300. // set receive pointer address  
  301.     enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);  
  302.     enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);  
  303. // set receive buffer end  
  304.     // ERXND defaults to 0x1FFF (end of ram)  
  305.     enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);  
  306.     enc28j60Write(ERXNDH, RXSTOP_INIT>>8);  
  307. // set transmit buffer start  
  308.     // ETXST defaults to 0x0000 (beginnging of ram)  
  309.     enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);  
  310.     enc28j60Write(ETXSTH, TXSTART_INIT>>8);       
  311. // do bank 2 stuff  
  312.     // enable MAC receive  
  313.     enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);  
  314. // bring MAC out of reset  
  315.     enc28j60Write(MACON2, 0x00);  
  316. // enable automatic padding and CRC operations  
  317.     enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);  
  318. // enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);  
  319.     // set inter-frame gap (non-back-to-back)  
  320.     enc28j60Write(MAIPGL, 0x12);  
  321.     enc28j60Write(MAIPGH, 0x0C);  
  322. // set inter-frame gap (back-to-back)  
  323.     enc28j60Write(MABBIPG, 0x12);  
  324. // Set the maximum packet size which the controller will accept  
  325.     enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);    
  326.     enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);  
  327. // do bank 3 stuff  
  328.     // write MAC address  
  329.     // NOTE: MAC address in ENC28J60 is byte-backward  
  330.     enc28j60Write(MAADR5, UIP_ETHADDR0);  
  331.     enc28j60Write(MAADR4, UIP_ETHADDR1);  
  332.     enc28j60Write(MAADR3, UIP_ETHADDR2);  
  333.     enc28j60Write(MAADR2, UIP_ETHADDR3);  
  334.     enc28j60Write(MAADR1, UIP_ETHADDR4);  
  335.     enc28j60Write(MAADR0, UIP_ETHADDR5);    
  336. // no loopback of transmitted frames  
  337.     enc28j60PhyWrite(PHCON2, PHCON2_HDLDIS);  
  338. // switch to bank 0  
  339.     enc28j60SetBank(ECON1);  
  340. // enable interrutps  
  341.     enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);  
  342. // enable packet reception   
  343.     enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);        
  344. }  
  345. </span>  



          在上面文件中有一个delay_100ns函数,为什么要写这个函数呢,看了enc28j60的输入输出的时序之后发现在cs置低之后只要要保持100ns,所以每次在写入之前都要延迟100ns左右。cc2530的时钟是32MHz,所以差不多3个机器周期就是100ns了。这个是要注意的地方,我在这之前,调试了半天,一直都没发现有网络数据包出来,然后再仔细读了datasheet才发现的。
       这个驱动根据datasheet写,或者参考网上的,哈哈,只要能实现就行了。          
       有了以上驱动程序就很好移植了! 废话不多说,直接给移植步骤。
       在网上下载源码,我用的是uip0.9版本。编译环境是IAR,因为cc2530用的是IAR开发环境。

       接下来建立工程,如下图所示:

 

          将spi.c enc28j60.c即相关头文件放在driver目录下,将uip.c uip_arp.c uip_arch.c还有相关头文件放在uip目录下,
linker目录下放的是IAR8051的连接文件(可以不用),将应用程序main.c app.c app.h文件放在user目录下。
      将uip源代码中unix文件夹中的main函数改一下,其中tapdev_read函数替换成我们的dev_poll,将tapdev_send替换成dev_send,然后将http相关的东西删去,我们先实现简单的功能。
      根据源码文件夹中的doc文档,写个简单的历程。

       app.c的代码如下:

 

[cpp]  view plain copy
  1. <span style="font-size:18px;">#include "app.h"  
  2. #include "uip.h"  
  3. void example1_init(void)   
  4. {  
  5.    uip_listen(HTONS(1234));  
  6. }  
  7. void example1_appcall(void)  
  8. {  
  9.    struct example1_state *s;  
  10.    s = (struct example1_state *)uip_conn->appstate;    
  11.    if(uip_connected()) {  
  12.       s->state = WELCOME_SENT;  
  13.       uip_send("Welcome!\n", 9);  
  14.       return;  
  15.    }   
  16.   
  17.    if(uip_acked() && s->state == WELCOME_SENT) {  
  18.       s->state = WELCOME_ACKED;  
  19.    }  
  20.    if(uip_newdata()) {  
  21.       uip_send("ok\n", 3);  
  22.    }  
  23.    if(uip_rexmit()) {  
  24.       switch(s->state) {  
  25.       case WELCOME_SENT:  
  26.          uip_send("Welcome!\n", 9);  
  27.          break;  
  28.       case WELCOME_ACKED:  
  29.          uip_send("ok\n", 3);  
  30.          break;  
  31.       }  
  32.    }  
  33. }</span>  

      对了,还有个重要的问题,就是大小端的问题,这个也是我调试好久未果的一个经验。cc2530是8051内核的,是小端,所以在uipopt.h文件中做如下改动
#ifndef BYTE_ORDER
#define BYTE_ORDER     LITTLE_ENDIAN
#endif /* BYTE_ORDER */  
      还有个编译设置的问题,具体按照如下来:

 

     好了,然后编译连接,过程中可能有一些警告和错误,一个一个耐心排除,很容易。
     用网线连上电脑,然后打开命令终端,输入ping 219.223.173.242  我主机ip是219.223.173.243
    如下结果:

            

 

        然后打开网络调试助手

 

 

      如程序需要的结果相同,哈哈!过几天实现一个web服务器!
    接下来的工作就是将uip移植到z-stack上,在cc2530上实现网关的功能!
    有需要源码的可以联系我!

这篇关于UIP移植到CC2530上的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1010592

相关文章

FreeRTOS-基本介绍和移植STM32

FreeRTOS-基本介绍和STM32移植 一、裸机开发和操作系统开发介绍二、任务调度和任务状态介绍2.1 任务调度2.1.1 抢占式调度2.1.2 时间片调度 2.2 任务状态 三、FreeRTOS源码和移植STM323.1 FreeRTOS源码3.2 FreeRTOS移植STM323.2.1 代码移植3.2.2 时钟中断配置 一、裸机开发和操作系统开发介绍 裸机:前后台系

RT-Thread(Nano版本)的快速移植(基于NUCLEO-F446RE)

目录 概述 1 RT-Thread 1.1 RT-Thread的版本  1.2 认识Nano版本 2 STM32F446U上移植RT-Thread  2.1 STM32Cube创建工程 2.2 移植RT-Thread 2.2.1 安装RT-Thread Packet  2.2.2 加载RT-Thread 2.2.3 匹配相关接口 2.2.3.1 初次编译代码  2.2.3.

libmad音频解码库-Linux交叉编译移植

下载并解压libmad-0.15.1b.tar.gz 下载链接:https://downloads.sourceforge.net/mad/libmad-0.15.1b.tar.gz $tar -xvf libmad-0.15.1b.tar.gz$cd libmad-0.15.1b 1、先执行下面的命令:这条命令是为了适配高版本的gcc,因为高版本的gcc已经将-fforce-mem去除了:

arm linux lua移植

lua: lua home 1.下载lua源码 lua下载 lua-5.3.4.tar.gz 2.解压: tar xvf lua-5.3.4.tar.gz 3.修改makefile and luaconf.h $修改 lua-5.3.4/Makefile #INSTALL_TOP= /usr/local INSTALL_TOP= $(shell pwd)/out #修改安装目录(当前目录/o

s3c2440---PWM使用之蜂鸣器驱动移植

一、蜂鸣器驱动介绍 1.1.什么是蜂鸣器               蜂鸣器是一种简单的声响发生器,常用于电子产品中作为警示或提醒作用。其基本原理是通过交替改变直流电的电压方向来产生声音,一般使用交替电流产生声音会比较稳定。 1.2.蜂鸣器的类别 1.有源蜂鸣器 1)结构原理 有源蜂鸣器内部自带振荡源,只需接通电源即可发声。内部电路会自动产生一定频率的振荡信号,从而驱动蜂鸣器发声。

CC2530单片机介绍

一、什么是CC2530? CC2530单片机是一款高性能、低功耗的片上系统解决方案,专门用于2.4GHz IEEE 802.15.4、ZigBee和RF4CE应用。它结合了先进的RF收发器、业界标准的增强型8051 CPU、系统内可编程闪存、8KB RAM以及其他许多强大功能。 CC2530具有四种不同闪存版本:CC2530F32/64/128/256,分别具有32/64/128/256KB的

【GD32】---- 移植工程模板及点灯测试

1 新建模板文件夹 新建一个名叫03_GD32TemplateProject的文件夹,用于建造工程模板 2 移植官方库文件 在模板文件夹里新建5个文件夹,分别存放官方库文件和系统驱动文件 01_main 存放main函数 02_Startup 存放系统启动文件 03_System 存放官方的系统文件 04_Firmware_PeripheralDriver 存放官方

[rk3588 ubuntu20.04]移植ROS2

目录 1 使用命令行安装ROS2 1.1设置语言 1.2添加源 1.3安装ROS2 1.4设置环境变量 2 在编译源码阶段安装ROS2 2.1调整roofts.img大小 2.2 安装ROS2 3 ROS2功能测试 1 使用命令行安装ROS2 1.1设置语言         设置语言为UTF-8。 sudo apt update && sudo apt insta

让linux下无线网卡变身随身wifi----hostapd移植-Nazgul

有了前面的检测,确定了我们的网卡是能够拥有热点共享功能的,但是如何让它共享出来呢? 于是有了这篇文章的诞生,hostapd移植 hostapd    可以让我们的网线网卡变成热点 1、下载     git clone git://w1.fi/srv/git/hostap.git   得到hostap目录,但是里面wpa_supplicant and hostapd的结合在

让linux下无线网卡变身随身wifi----前言--iw移植-Nazgul

最痛苦的事莫过于--上班 最最痛苦的事莫过于--上班有网不能上 最最最痛苦的事莫过于--上班有网能上却没有wifi 最最最最痛苦的事莫过于--你有无线网卡却没有U口可插 最最最最最痛苦的事莫过于--有U口插却发现U口只在开发板上 最最最最最最痛苦的事莫过于--开发板上有u口但是跑的是linux 最最最最最最最痛苦的事莫过于--linux能驱动网卡,但是如何共享出wifi来啊 于是,,,