stm32使用LWIP实现DHCP客户端
来源:互联网 发布时间:2018-11-06 分享至微信


LWIP是一款开源的嵌入式网络协议栈,支持的功能很多,而且能在多任务环境下和单任务裸机环境下跑,今天说说他的移植过程,芯片为STM32,网卡为ENC28J60,无操作系统


首先下载LWIP的源代码,我下载的是1.4.1的源码,下载后解压,文件结构如图



将这四个目录中的文件全部拷贝到工程中,API是一些socket通讯的接口,需要在多任务的环境下实现,core里面存放的内核源码,我们主要使用IPV4,include目录下是需要包含的目录,lwip只要求我们包含include目录,里面的内层目录会自动找到,最后建立的工程目录如下



好了,此时源码已经做好,还有需要做的,在include目录下新建一个文件夹,必须叫arch,里面存放这几个文件,自己新建



文件的具体内容如下


cc.h


/*


* Copyright (c) 2001-2003 Swedish Institute of Computer Science.


* All rights reserved.


*


* Redistribution and use in source and binary forms, with or without modification,


* are permitted provided that the following conditions are met:


*


* 1. Redistributions of source code must retain the above copyright notice,


* this list of conditions and the following disclaimer.


* 2. Redistributions in binary form must reproduce the above copyright notice,


* this list of conditions and the following disclaimer in the documentation


* and/or other materials provided with the distribution.


* 3. The name of the author may not be used to endorse or promote products


* derived from this software without specific prior written permission.


*


* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED


* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF


* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT


* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,


* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT


* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS


* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN


* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING


* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY


* OF SUCH DAMAGE.


*


* This file is part of the lwIP TCP/IP stack.


*


* Author: Adam Dunkels


*


*/


#ifndef __CC_H__


#define __CC_H__




#include "cpu.h"




//编译器无关的数据类型定义


typedef unsigned char u8_t;


typedef signed char s8_t;


typedef unsigned short u16_t;


typedef signed short s16_t;


typedef unsigned long u32_t;


typedef signed long s32_t;


typedef u32_t mem_ptr_t;


typedef int sys_prot_t;




//lwip调试的时候数据类型定义


#define U16_F "hu"


#define S16_F "d"


#define X16_F "hx"


#define U32_F "u"


#define S32_F "d"


#define X32_F "x"


#define SZT_F "uz"






//根据不同的编译器的符号定义


#if defined (__ICCARM__)




#define PACK_STRUCT_BEGIN


#define PACK_STRUCT_STRUCT


#define PACK_STRUCT_END


#define PACK_STRUCT_FIELD(x) x


#define PACK_STRUCT_USE_INCLUDES




#elif defined (__CC_ARM)




#define PACK_STRUCT_BEGIN __packed


#define PACK_STRUCT_STRUCT


#define PACK_STRUCT_END


#define PACK_STRUCT_FIELD(x) x




#elif defined (__GNUC__)




#define PACK_STRUCT_BEGIN


#define PACK_STRUCT_STRUCT __attribute__ ((__packed__))


#define PACK_STRUCT_END


#define PACK_STRUCT_FIELD(x) x




#elif defined (__TASKING__)




#define PACK_STRUCT_BEGIN


#define PACK_STRUCT_STRUCT


#define PACK_STRUCT_END


#define PACK_STRUCT_FIELD(x) x




#endif




#define LWIP_PLATFORM_ASSERT(x) //do { if(!(x)) while(1); } while(0)




#endif /* __CC_H__ */




cpu.h






/*


* Copyright (c) 2001-2003 Swedish Institute of Computer Science.


* All rights reserved.


*


* Redistribution and use in source and binary forms, with or without modification,


* are permitted provided that the following conditions are met:


*


* 1. Redistributions of source code must retain the above copyright notice,


* this list of conditions and the following disclaimer.


* 2. Redistributions in binary form must reproduce the above copyright notice,


* this list of conditions and the following disclaimer in the documentation


* and/or other materials provided with the distribution.


* 3. The name of the author may not be used to endorse or promote products


* derived from this software without specific prior written permission.


*


* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED


* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF


* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT


* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,


* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT


* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS


* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN


* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING


* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY


* OF SUCH DAMAGE.


*


* This file is part of the lwIP TCP/IP stack.


*


* Author: Adam Dunkels


*


*/


#ifndef __CPU_H__


#define __CPU_H__




//定义cpu的数据模式,大端小端


#define BYTE_ORDER LITTLE_ENDIAN




#endif /* __CPU_H__ */




perf.h






#ifndef __PERF_H__


#define __PERF_H__




//用于lwip内置的统计功能


//不使能定义为空就可以了


#define PERF_START /* null definition */


#define PERF_STOP(x) /* null definition */




#endif /* __PERF_H__ */




sys_arch.h






#ifndef __SYS_RTXC_H__


#define __SYS_RTXC_H__






void init_lwip_timer(void); //初始化LWIP定时器




u8_t timer_expired(u32_t *last_time,u32_t tmr_interval); //定时器超时判断




#endif /* __SYS_RTXC_H__ */




sya_arch.c--注意该文件要加入源文件列表中,这是c文件哦






#include "lwip/debug.h"


#include "lwip/def.h"


#include "lwip/sys.h"


#include "lwip/mem.h"


#include "timerx.h"




//初始化LWIP定时器


void init_lwip_timer(void)


{


TIM6_Int_Init(1000,719);//100Khz计数频率,计数到100为10ms


}




//为LWIP提供计时


extern u32_t lwip_timer;//lwip 计时器,每10ms增加1.




u32_t sys_now(void)


{


return lwip_timer;


}




//定时器超时判断


//last_time:最近时间


//tmr_interval:定时器溢出周期


u8_t timer_expired(u32_t *last_time,u32_t tmr_interval)


{


u32_t time;


time = *last_time;


if((lwip_timer-time)>=tmr_interval){


*last_time = lwip_timer;


return 1;


}


return 0;


}




可以看到我们定义了定时器,那么就要修改相关的定时器文件,文件如下




timerx.c






#include "timerx.h"






u32 lwip_timer=0;//lwip 计时器,每10ms增加1.




//定时器6中断服务程序


void TIM6_IRQHandler(void)


{




if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源


{


TIM_ClearITPendingBit(TIM6, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源


lwip_timer++;//lwip计时器增加1


}




}











//基本定时器6中断初始化


//这里时钟选择为APB1的2倍,而APB1为36M


//arr:自动重装值。


//psc:时钟预分频数


//这里使用的是定时器3!


void TIM6_Int_Init(u16 arr,u16 psc)


{


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


NVIC_InitTypeDef NVIC_InitStructure;




RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //时钟使能




TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms


TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率


TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim


TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式


TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位



TIM_ITConfig( TIM6,TIM_IT_Update"TIM_IT_Trigger,ENABLE);//使能定时器6更新触发中断



TIM_Cmd(TIM6, ENABLE); //使能TIMx外设



NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //TIM3中断


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级0级


NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级3级


NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能


NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


[ 新闻来源:互联网,更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj]
存入云盘 收藏
举报
全部评论

暂无评论哦,快来评论一下吧!