stm32-ucos移植lwip-1(raw)
之前在裸机环境下移植了lwip,功能还是很强大的,但是就我看来,这和uip其实差别也不大,其实lwip更强大的功能需要在操作系统之下才能发挥出来,今天就来做这个
首先我们需要移植操作系统,系统选择ucos2.91,移植过程网上都有,我就写点不同的
配置文件修改如下
/* ---------------------- MISCELLANEOUS ----------------------- */
#define OS_APP_HOOKS_EN 0u /* Application-defined hooks are called from the uC/OS-II hooks */
#define OS_ARG_CHK_EN 0u /* Enable (1) or Disable (0) argument checking */
#define OS_CPU_HOOKS_EN 1u /* uC/OS-II hooks are found in the processor port files */ #define OS_DEBUG_EN 0u /* Enable(1) debug variables */ #define OS_EVENT_MULTI_EN 0u /* Include code for OSEventPendMulti() */
#define OS_EVENT_NAME_EN 0u /* Enable names for Sem, Mutex, Mbox and Q */ #define OS_LOWEST_PRIO 63u /* Defines the lowest priority that can be assigned ... */
/* ... MUST NEVER be higher than 254! */ #define OS_MAX_EVENTS 10u /* Max. number of event control blocks in your application */
#define OS_MAX_FLAGS 5u /* Max. number of Event Flag Groups in your application */
#define OS_MAX_MEM_PART 0u /* Max. number of memory partitions */
#define OS_MAX_QS 5u /* Max. number of queue control blocks in your application */
#define OS_MAX_TASKS 10u /* Max. number of tasks in your application, MUST be >= 2 */ #define OS_SCHED_LOCK_EN 1u /* Include code for OSSchedLock() and OSSchedUnlock() */ #define OS_TICK_STEP_EN 1u /* Enable tick stepping feature for uC/OS-View */
#define OS_TICKS_PER_SEC 200u /* Set the number of ticks in one second 1000/200 = 5 5ms中断一次 */ /* --------------------- TASK STACK SIZE ---------------------- */
#define OS_TASK_TMR_STK_SIZE 128u /* Timer task stack size (# of OS_STK wide entries) */
#define OS_TASK_STAT_STK_SIZE 128u /* Statistics task stack size (# of OS_STK wide entries) */
#define OS_TASK_IDLE_STK_SIZE 128u /* Idle task stack size (# of OS_STK wide entries) */ /* --------------------- TASK MANAGEMENT ---------------------- */
#define OS_TASK_CHANGE_PRIO_EN 1u /* Include code for OSTaskChangePrio() */
#define OS_TASK_CREATE_EN 1u /* Include code for OSTaskCreate() */
#define OS_TASK_CREATE_EXT_EN 1u /* Include code for OSTaskCreateExt() */
#define OS_TASK_DEL_EN 1u /* Include code for OSTaskDel() */
#define OS_TASK_NAME_EN 1u /* Enable task names */
#define OS_TASK_PROFILE_EN 1u /* Include variables in OS_TCB for profiling */
#define OS_TASK_QUERY_EN 1u /* Include code for OSTaskQuery() */
#define OS_TASK_REG_TBL_SIZE 1u /* Size of task variables array (#of INT32U entries) */
#define OS_TASK_STAT_EN 1u /* Enable (1) or Disable(0) the statistics task */
#define OS_TASK_STAT_STK_CHK_EN 1u /* Check task stacks from statistic task */
#define OS_TASK_SUSPEND_EN 1u /* Include code for OSTaskSuspend() and OSTaskResume() */
#define OS_TASK_SW_HOOK_EN 1u /* Include code for OSTaskSwHook() */ /* ----------------------- EVENT FLAGS ------------------------ */
#define OS_FLAG_EN 1u /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
#define OS_FLAG_ACCEPT_EN 1u /* Include code for OSFlagAccept() */
#define OS_FLAG_DEL_EN 1u /* Include code for OSFlagDel() */
#define OS_FLAG_NAME_EN 1u /* Enable names for event flag group */
#define OS_FLAG_QUERY_EN 1u /* Include code for OSFlagQuery() */
#define OS_FLAG_WAIT_CLR_EN 1u /* Include code for Wait on Clear EVENT FLAGS */
#define OS_FLAGS_NBITS 16u /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */ /* -------------------- MESSAGE MAILBOXES --------------------- */
#define OS_MBOX_EN 1u /* Enable (1) or Disable (0) code generation for MAILBOXES */
#define OS_MBOX_ACCEPT_EN 1u /* Include code for OSMboxAccept() */
#define OS_MBOX_DEL_EN 1u /* Include code for OSMboxDel() */
#define OS_MBOX_PEND_ABORT_EN 1u /* Include code for OSMboxPendAbort() */
#define OS_MBOX_POST_EN 1u /* Include code for OSMboxPost() */
#define OS_MBOX_POST_OPT_EN 1u /* Include code for OSMboxPostOpt() */
#define OS_MBOX_QUERY_EN 1u /* Include code for OSMboxQuery() */ /* --------------------- MEMORY MANAGEMENT -------------------- */
#define OS_MEM_EN 1u /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_NAME_EN 1u /* Enable memory partition names */
#define OS_MEM_QUERY_EN 1u /* Include code for OSMemQuery() */ /* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
#define OS_MUTEX_EN 1u /* Enable (1) or Disable (0) code generation for MUTEX */
#define OS_MUTEX_ACCEPT_EN 1u /* Include code for OSMutexAccept() */
#define OS_MUTEX_DEL_EN 1u /* Include code for OSMutexDel() */
#define OS_MUTEX_QUERY_EN 1u /* Include code for OSMutexQuery() */ /* ---------------------- MESSAGE QUEUES ---------------------- */
#define OS_Q_EN 1u /* Enable (1) or Disable (0) code generation for QUEUES */
#define OS_Q_ACCEPT_EN 1u /* Include code for OSQAccept() */
#define OS_Q_DEL_EN 1u /* Include code for OSQDel() */
#define OS_Q_FLUSH_EN 1u /* Include code for OSQFlush() */
#define OS_Q_PEND_ABORT_EN 1u /* Include code for OSQPendAbort() */
#define OS_Q_POST_EN 1u /* Include code for OSQPost() */
#define OS_Q_POST_FRONT_EN 1u /* Include code for OSQPostFront() */
#define OS_Q_POST_OPT_EN 1u /* Include code for OSQPostOpt() */
#define OS_Q_QUERY_EN 1u /* Include code for OSQQuery() */ /* ------------------------ SEMAPHORES ------------------------ */
#define OS_SEM_EN 1u /* Enable (1) or Disable (0) code generation for SEMAPHORES */
#define OS_SEM_ACCEPT_EN 1u /* Include code for OSSemAccept() */
#define OS_SEM_DEL_EN 1u /* Include code for OSSemDel() */
#define OS_SEM_PEND_ABORT_EN 1u /* Include code for OSSemPendAbort() */
#define OS_SEM_QUERY_EN 1u /* Include code for OSSemQuery() */
#define OS_SEM_SET_EN 1u /* Include code for OSSemSet() */ /* --------------------- TIME MANAGEMENT ---------------------- */
#define OS_TIME_DLY_HMSM_EN 1u /* Include code for OSTimeDlyHMSM() */
#define OS_TIME_DLY_RESUME_EN 1u /* Include code for OSTimeDlyResume() */
#define OS_TIME_GET_SET_EN 1u /* Include code for OSTimeGet() and OSTimeSet() */
#define OS_TIME_TICK_HOOK_EN 1u /* Include code for OSTimeTickHook() */ /* --------------------- TIMER MANAGEMENT --------------------- */
#define OS_TMR_EN 0u /* Enable (1) or Disable (0) code generation for TIMERS */
#define OS_TMR_CFG_MAX 16u /* Maximum number of timers */
#define OS_TMR_CFG_NAME_EN 1u /* Determine timer names */
#define OS_TMR_CFG_WHEEL_SIZE 8u /* Size of timer wheel (#Spokes) */
#define OS_TMR_CFG_TICKS_PER_SEC 10u /* Rate at which timer management task runs (Hz) */
因为之前我们有一个lwip_timer的变量,代表了网络系统的时钟心跳,使用的是定时器6,这时候定时器6被操作系统占用了,我们就设置一个新的定时器7作为网络心跳定时器,如下
//定时器6中断服务程序
void TIM6_IRQHandler(void)
{
OSIntEnter(); //进入中断
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM6, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
OSTimeTick(); //调用ucos的时钟服务程序 }
OSIntExit(); //触发任务切换软中断
} //基本定时器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 = ; //设置时钟分割: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 = ; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
} //基本定时器7中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器7!
void TIM7_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = ; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM7, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig( TIM7,TIM_IT_Update|TIM_IT_Trigger,ENABLE);//使能定时器6更新触发中断 TIM_Cmd(TIM7, ENABLE); //使能TIMx外设 NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = ; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = ; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
} u32 lwip_timer=;//lwip 计时器,每10ms增加1. //定时器7中断服务程序
void TIM7_IRQHandler(void)
{
OSIntEnter(); //进入中断
if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM7, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
lwip_timer++;//lwip计时器增加1
}
OSIntExit(); //触发任务切换软中断
}
到这里基本上就可以跑系统了(系统具体移植参见之前的文章)
接下来就是创建任务
void start_task(void *pdata)
{
OS_CPU_SR cpu_sr=;
pdata = pdata;
OSStatInit(); //初始化统计任务.这里会延时1秒钟左右
OS_ENTER_CRITICAL(); //进入临界区(无法被中断打断)
OSTaskCreate(led1_task,(void *),(OS_STK*)&LED1_TASK_STK[LED1_STK_SIZE-],LED1_TASK_PRIO);
OSTaskCreate(led2_task,(void *),(OS_STK*)&LED2_TASK_STK[LED2_STK_SIZE-],LED2_TASK_PRIO);
OSTaskCreate(lwip_task,(void *),(OS_STK*)&LWIP_TASK_STK[LWIP_STK_SIZE-],LWIP_TASK_PRIO);
OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
OS_EXIT_CRITICAL(); //退出临界区(可以被中断打断)
}
我们将lwip创建成为了一个单独的任务,该任务的运行代码如下
//创建任务堆栈空间
OS_STK LWIP_TASK_STK[LWIP_STK_SIZE]; #define CLOCKTICKS_PER_MS 10 //定义时钟节拍 static ip_addr_t ipaddr, netmask, gw; //定义IP地址
struct netif enc28j60_netif; //定义网络接口
u32_t input_time;
u32_t last_arp_time;
u32_t last_tcp_time;
u32_t last_ipreass_time; u32_t last_dhcp_fine_time;
u32_t last_dhcp_coarse_time;
u32 dhcp_ip=; //LWIP查询
void LWIP_Polling(void)
{
if(timer_expired(&input_time,)) //接收包,周期处理函数
{
ethernetif_input(&enc28j60_netif);
}
if(timer_expired(&last_tcp_time,TCP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//TCP处理定时器处理函数
{
tcp_tmr();
}
if(timer_expired(&last_arp_time,ARP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//ARP处理定时器
{
etharp_tmr();
}
if(timer_expired(&last_ipreass_time,IP_TMR_INTERVAL/CLOCKTICKS_PER_MS))//IP重新组装定时器
{
ip_reass_tmr();
}
} void lwip_task(void *pdata)
{
u8 t_client_cnt = ;
IP4_ADDR(&ipaddr, , , , ); //设置本地ip地址
IP4_ADDR(&gw, , , , ); //网关
IP4_ADDR(&netmask, , , , ); //子网掩码
//初始化LWIP定时器
init_lwip_timer();
//初始化LWIP协议栈,执行检查用户所有可配置的值,初始化所有的模块
lwip_init();
//添加网络接口
while((netif_add(&enc28j60_netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input)==NULL))
{
LCD_ShowString(,,,,(u8*)"ENC28J60 Init Failed ",LCD_BLACK);
OSTimeDly();
LCD_ShowString(,,,,(u8*)" ",LCD_BLACK);
OSTimeDly();
}
LCD_ShowString(,,,,(u8*)"ENC28J60 Init OK ",LCD_BLACK);
//注册默认的网络接口
netif_set_default(&enc28j60_netif);
//建立网络接口用于处理通信
netif_set_up(&enc28j60_netif); Tcp_Client_Init();//初始化tcp客户端 LCD_ShowString(,,,,(u8*)"TCP CLIENT INIT ",LCD_BLACK);
LCD_ShowString(,,,,(u8*)"TCP CLIENT Disconnect ",LCD_BLACK);
LCD_ShowString(,,,,(u8*)"RX: ",LCD_BLACK);
LCD_ShowString(,,,,(u8*)"TX: ",LCD_BLACK); while()
{
OSTimeDly();//注意这个延时,和定时器7初始化的时间必须一致,CLOCKTICKS_PER_MS一致
LWIP_Polling();
if((lwip_tcp_client_flag&LWIP_CONNECTED)==LWIP_CONNECTED)
{
LCD_ShowString(,,,,(u8*)"TCP CLIENT Connect ",LCD_BLACK);
if(keyValue == KEY_RIGHT)
{
t_client_cnt++;
sprintf((char*)lwip_client_buf,"tcp_client send %d\r\n",t_client_cnt);
LCD_ShowString(,,,,(u8*)lwip_client_buf,LCD_BLACK);//显示当前发送数据
lwip_tcp_client_flag |= LWIP_SEND_DATA; //标记有数据需要发送
keyValue = ;
}
}
else
{
// Tcp_Client_Connect_Remotehost();//没有连接上,此时处于TCP客户端模式,则尝试重新连接
} if((lwip_tcp_client_flag&LWIP_NEW_DATA)==LWIP_NEW_DATA)
{
LCD_ShowString(,,,,(u8*)lwip_client_buf,LCD_BLACK);
lwip_tcp_client_flag &=~LWIP_NEW_DATA; //清除接受数据的标志
}
}
}
和之前的raw模式不带系统差不多,这一章只是一个引导,不想这么玩的可以看下一章直接使用netconn,好了到此为止
哦对了,代码链接在下面
http://download.csdn.net/detail/dengrengong/8599061
stm32-ucos移植lwip-1(raw)的更多相关文章
- ucos实时操作系统学习笔记——操作系统在STM32的移植
使用ucos实时操作系统是在上学的时候,导师科研项目中.那时候就是网上找到操作系统移植教程以及应用教程依葫芦画瓢,功能实现也就罢了,没有很深入的去研究过这个东西.后来工作了,闲来无聊就研究了一下这个只 ...
- LwIP学习笔记——STM32 ENC28J60移植与入门
0.前言 去年(2013年)的整理了LwIP相关代码,并在STM32上"裸奔"成功.一直没有时间深入整理,在这里借博文整理总结.LwIP的移植过程细节很多,博文也不可能一一 ...
- [stm32][ucos][ucgui] 2、LED闪烁、串口、滑块、文本编辑框简单例程
上一篇:[stm32][ucos] 1.基于ucos操作系统的LED闪烁.串口通信简单例程 * 内容简述: 本例程操作系统采用ucos2.86a版本, 建立了7个任务 任务名 ...
- ucos移植指南
指定堆栈数据类型(宽度) typedef unsigned int OS_STK; 指定Ucos移植方法3中保存cpu状态寄存器的变量的宽度 typedef unsigned int OS_CPU_S ...
- STM32F107移植LWIP
STM32F107上移植LWIP2.0.3 因为最近需要在STM32F107上实现TCP/IP协议栈,所以网上查了一下,准备使用LWIP,虽然大多数用的是1.4.1版本但是官方说2系大版本修复了1.4 ...
- emWin5.24 VS2008模拟LCD12864 stm32 RTX移植 【worldsing笔记】
emWin for 12864 并口移植 源代码下载:RTX_emWin5.24_Keil_VS2008-20141122.zip 硬件环境: CPU: stm32f103ve LCD:st7 ...
- 在stm32上移植wpa_supplicant(一)
wifi芯片为88w8686,已经写好了驱动,用的是SPI方式,接下来准备移植wpa_supplicant.参考的资料为一篇论文----<基于微控制器的WPA技术研究与应用>. wpa_s ...
- UCOS移植心得(
移植UCOS之前,你首先应该做好三件事: 1.弄懂UCOS,这是谁都知道的哦 ^_^ 2. 弄懂你想要移植到的硬件平台 3. 清楚你使用的编译器是如何处理函数的局部变量和怎么样处理函数间的参数传递 这 ...
- 移植LWIP(ENC28J60)
上图就是整个移植的基本思路,非常清晰的三个层次.其实想想,本质上就是收发数据,只是LWIP协议通过对数据的封装可以实现网络传输.从图中我们就可以看到这里首先需要ENC28J60的驱动,这个驱动需 ...
随机推荐
- TCP的四次挥手
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭.这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接.收到一个 FIN只意味着这一方向上没有数据流动, 一个TCP连接 ...
- Zookeeper: configuring on centos7
thispassage is referenced, appreciated. ZooKeeper installation: Download from this site Install java ...
- webview h5页面 关闭
说明:在 ios 安卓 客户端上的h5页面执行完毕关闭h5页面 引入的js在文件中的xhdoctor_mobile.rar
- Slow HTTP Denial of Service Attack 漏洞解决
修改tomcat conf 下 server.xml 文件 <Connector port="8080" protocol="HTTP/1.1" con ...
- [转]Android Shape渲染的使用(经典,学习研究不后悔)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://mzh3344258.blog.51cto.com/1823534/1215749 ...
- 8--UI 初步认识 简易计算器
UI是App的根基:一个App应该是先有UI界面,然后在UI的基础上增加实用功能(2)UI相对简单易学:UI普遍是学习过程中最简单的一块,能快速拥有成就感和学习兴趣(3)UI至关重要:开发中的绝大部分 ...
- eclipse,android Localization (Internationalization) 安卓本地化(国际化)
1.创建新的资源文件,名字保持一致.提示"已存在",继续. 2.使用“语言”作为识别器,然后选择相应的语言代码.Tips:其他的适配,如国家.屏幕大小等,也是通过这里的识别器实现适 ...
- 如何用好 Google 搜索引擎?
1.双引号 把搜索词放在双引号中,代表完全匹配搜索,也就是说搜索结果返回的页面包含双引号中出现的所有的词,连顺序也必须完全匹配.bd和Google 都支持这个指令.例如搜索: “seo方法图片” 2. ...
- 【从汉字中提取数字】不用公式,不用VBA,如此简单的方法你是否用过?
转自:http://huaban.com/pins/19664410 具体操作过程请看附图动画:
- laytpl.js 模板使用记录
{{# for(var j = 0, len = d.length; j < len; j++){ }} <div class="pure-u-1-5 pure-u-sm-1 p ...