Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
网络学习营
【LwIP学习营】【第二周】 telnet 控制ntp
发布于 2018-05-26 10:11:14 浏览:2689
订阅该版
* 本帖最后由 hcb900330 于 2018-5-26 10:11 编辑 * 硬件:STM32F407vgt6 软件: keil,evn0.7.0,rtt3.0.3 1.背景: telnet通过添加组件,很快完成,功能测试完成。 另外一个要求是完成weather功能,个人觉得ntp功能比这个天气功能在实际项目中实用多了,所以就暂时先完成ntp功能。 2.问题: 开启ntp以后,默认打开了posxi,导致shell不能正常使用。 shell不能使用,不知道从哪里下手,从网上找了一篇 王希同学的贴子 [https://www.rt-thread.org/qa/thread-6908-1-1.html](https://www.rt-thread.org/qa/thread-6908-1-1.html),意思大概是由于开了dfs,所以需要重新定向consle接口 int fgetc(FILE *f) { char ch; RT_ASSERT(_redirection.rx_sem != RT_NULL); while (rt_device_read(_redirection.device, 0, &ch, 1) != 1) rt_sem_take(_redirection.rx_sem, RT_WAITING_FOREVER); return (int)ch; } 巧合的是王希也在这个学习营里,还是得到了他的热心帮助,在这里谢谢了,还有他的话我也很认同,对于底层,我们还是要了解的(这也是我参加这个学习营的初衷,深刻理解lwip协议),单纯的使用组件也会遇到很多问题,虽然这次问题是有stm32f4xxbsp包里面问题(后面我会提到),但是通过这种方法,了解shell的工作流程,还有libc的初始化。 这种方法主要有以下几个方面: 1.)在shell.c中添加如下代码,让shell正常工作 void finsh_thread_entry(void *parameter) { char ch; /* normal is echo mode */ shell->echo_mode = 1; #ifdef RT_USING_DFS rt_device_t console; extern void rt_redirection_set_device(const char *device_name); #endif #ifndef RT_USING_DFS /* set console device as shell device */ if (shell->device == RT_NULL) { rt_device_t console = rt_console_get_device(); if (console) { finsh_set_device(console->parent.name); } } #else console = rt_console_get_device(); if (console) { rt_redirection_set_device(console->parent.name); } #endif 2.)在telnet更改为输入源以后,把输入接口添加到telnet static void telnet_thread(void* parameter) { #define RECV_BUF_LEN 64 struct sockaddr_in addr; socklen_t addr_size; rt_uint8_t recv_buf[RECV_BUF_LEN]; rt_int32_t recv_len = 0; if ((telnet->server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { rt_kprintf("telnet: create socket failed
"); return; } addr.sin_family = AF_INET; addr.sin_port = htons(TELNET_PORT); addr.sin_addr.s_addr = INADDR_ANY; rt_memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero)); if (bind(telnet->server_fd, (struct sockaddr *) &addr, sizeof(struct sockaddr)) == -1) { rt_kprintf("telnet: bind socket failed
"); return; } if (listen(telnet->server_fd, TELNET_BACKLOG) == -1) { rt_kprintf("telnet: listen socket failed
"); return; } /* register telnet device */ telnet->device.type = RT_Device_Class_Char; telnet->device.init = telnet_init; telnet->device.open = telnet_open; telnet->device.close = telnet_close; telnet->device.read = telnet_read; telnet->device.write = telnet_write; telnet->device.control = telnet_control; /* no private */ telnet->device.user_data = RT_NULL; /* register telnet device */ rt_device_register(&telnet->device, "telnet", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STREAM); while (1) { rt_kprintf("telnet: waiting for connection
"); /* grab new connection */ if ((telnet->client_fd = accept(telnet->server_fd, (struct sockaddr *) &addr, &addr_size)) == -1) { continue; } rt_kprintf("telnet: new telnet client(%s:%d) connection, switch console to telnet...
", inet_ntoa(addr.sin_addr), addr.sin_port); /* process the new connection */ /* set console */ rt_console_set_device("telnet"); /* set finsh device */ #if defined(RT_USING_POSIX) // /* backup flag */ // dev_old_flag = ioctl(libc_stdio_get_console(), F_GETFL, (void *) RT_NULL); // /* add non-block flag */ // ioctl(libc_stdio_get_console(), F_SETFL, (void *) (dev_old_flag | O_NONBLOCK)); // /* set tcp shell device for console */ // libc_stdio_set_console("telnet", O_RDWR); #ifdef RT_USING_DFS rt_device_t console; extern void rt_redirection_set_device(const char *device_name); #endif #ifndef RT_USING_DFS /* set console device as shell device */ if (shell->device == RT_NULL) { rt_device_t console = rt_console_get_device(); if (console) { finsh_set_device(console->parent.name); } } #else console = rt_console_get_device(); if (console) { rt_redirection_set_device(console->parent.name); } #endif /* resume finsh thread, make sure it will unblock from last device receive */ rt_thread_t tid = rt_thread_find(FINSH_THREAD_NAME); if (tid) { rt_thread_resume(tid); rt_schedule(); } #else /* set finsh device */ finsh_set_device("telnet"); #endif /* RT_USING_POSIX */ /* set init state */ telnet->state = STATE_NORMAL; telnet->echo_mode = finsh_get_echo(); /* disable echo mode */ finsh_set_echo(0); /* output RT-Thread version and shell prompt */ #ifdef FINSH_USING_MSH msh_exec("version", strlen("version")); #endif rt_kprintf(FINSH_PROMPT); while (1) { /* try to send all data in tx ringbuffer */ send_to_client(telnet); /* do a rx procedure */ if ((recv_len = recv(telnet->client_fd, recv_buf, RECV_BUF_LEN, 0)) > 0) { process_rx(telnet, recv_buf, recv_len); } else { /* close connection */ client_close(telnet); break; } } } } 3.)关闭telnet后手动切换到finsh源 /* client close */ static void client_close(struct telnet_session* telnet) { /* set finsh device */ #if defined(RT_USING_POSIX) // ioctl(libc_stdio_get_console(), F_SETFL, (void *) dev_old_flag); // libc_stdio_set_console(RT_CONSOLE_DEVICE_NAME, O_RDWR); /* resume finsh thread, make sure it will unblock from last device receive */ #else finsh_set_device(RT_CONSOLE_DEVICE_NAME); #endif /* RT_USING_POSIX */ /* close connection */ close(telnet->client_fd); /* restore shell option */ finsh_set_echo(telnet->echo_mode); rt_kprintf("telnet: resume console to %s
", RT_CONSOLE_DEVICE_NAME); rt_console_set_device(CONSOLE_DEVICE); #ifdef RT_USING_DFS rt_device_t console; extern void rt_redirection_set_device(const char *device_name); #endif #ifndef RT_USING_DFS /* set console device as shell device */ if (shell->device == RT_NULL) { rt_device_t console = rt_console_get_device(); if (console) { finsh_set_device(console->parent.name); } } #else console = rt_console_get_device(); if (console) { rt_redirection_set_device(console->parent.name); } #endif rt_sem_release(telnet->read_notice); rt_thread_t tid1=rt_thread_self(); rt_thread_delete(tid1); } 3.stm32f407的bsp中,在rtt3.03中telnet设置的串口为RT_CONSOLE_DEVICE_NAME,而我们使用的CONSOLE_DEVICE,两个名字不统一,导致无法使用libc。rtt3.0.4已经修复了 4.注意点:如果使用了dfs 必须使用函数dfs_init(); 由于rtt3.0.3中的components有问题,需要手动添加,在rtt3.0.4中就可以自动添加dfs。 ![XEQ9Q_{])}55`%ZE92{~GDQ.png](https://oss-club.rt-thread.org/uploads/201805/26/100502p3dwgsqqswswa5a3.png) ![COQD0G]AC`2S(29N8ZQ[X~T.png](https://oss-club.rt-thread.org/uploads/201805/26/100611cnik3na4au5ya7ki.png) ![A%9~9]46T3]]PNKP54%BPRM.png](https://oss-club.rt-thread.org/uploads/201805/26/101109vg33g6878mdd6j6h.png)
查看更多
0
个回答
默认排序
按发布时间排序
暂无答案,快来添加答案吧
撰写答案
登录
注册新账号
关注者
0
被浏览
2.7k
关于作者
hcb900330
这家伙很懒,什么也没写!
提问
24
回答
37
被采纳
1
关注TA
发私信
相关问题
1
【LWIP学习营】第一关开发环境搭建
2
LWIP学习营第一周入门移植问题汇总贴
3
【LWIP学习营】f407+lan8720A小结
4
【LwIP学习营】【第一周】仅零散记录,无主题
5
【LWIP学习营】正点原子探索者F407+LAN8720第一周小结
6
【LwIP学习营】【第一周】网络通信基础及实现TCP 聊天客户端
7
【LwIP学习营】【第一周】LWIP移植
8
【LwIP学习营】【第一周】LWIP移植
9
【LwIP学习营】【第一周】开发板适配
10
【LwIP学习营】【第一周】环境搭建和配置验证
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
2
RT-Thread 发布 EtherKit开源以太网硬件!
3
rt-thread使用cherryusb实现虚拟串口
4
《C++20 图形界面程序:速度与渲染效率的双重优化秘籍》
5
《原子操作:程序世界里的“最小魔法单位”解析》
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部