【平头哥RVB2601开发板试用体验】基于NTP的网络校时及WIFI驱动Bug调试

简介: 基于NTP实现网络校时,并完成Wi-Fi驱动Bug调试

作者:czxin


NTP全称Network time Protocol,即网络时间协议,顾名思义就是通过与网络服务器之间通信来达到时间校准的协议,它是基于UDP的协议,记住这里的UDP,和后面遇到的WIFi驱动Bug密切相关。有了这个协议加上RTC外设的配合,便可以使运行的设备精准报时。


要实现这个功能,首先必须连接网络。RVB2601板载一颗WiFi芯片W800,提供了基于AT命令的驱动接口:W800模组AT指令集。


在YoC架构下,所有的网络由网络管理器netmgr负责,这里也不例外。我们需要将W800挂载到netmgr下。

static void network_init()
{
    w800_wifi_param_t w800_param;
    /* init wifi driver and network */
    w800_param.reset_pin      = PA21;
    w800_param.baud           = 1*1000000;
    w800_param.cs_pin         = PA15;
    w800_param.wakeup_pin     = PA25;
    w800_param.int_pin        = PA22;
    w800_param.channel_id     = 0;
    w800_param.buffer_size    = 4*1024;
    wifi_w800_register(NULL, &w800_param);
    app_netmgr_hdl = netmgr_dev_wifi_init();
    if (app_netmgr_hdl) {
        utask_t *task = utask_new("netmgr", 2 * 1024, QUEUE_MSG_COUNT, AOS_DEFAULT_APP_PRI);
        netmgr_service_init(task);
        netmgr_config_wifi(app_netmgr_hdl, "xxxxxxxx", 8, "xxxxxxxxxx", 10);
        netmgr_start(app_netmgr_hdl);
    }
}


这段代码来自例程webplayer,已经帮我们搭好了WiFi驱动和网络管理器之间的连接,只需要将“netmgr_config_wifi ”的第二个参数设为自己WiFi的SSID,第三个参数为SSID长度,然后第四个和第五个分别是密码和密码长度。


不过光有netmgr,我们的联网体验还不能达到最好。可以加入微服务组件uService,让系统为我们提供消息的发布服务。通过下面代码中的订阅方式,用户可以轻松掌握网络连接状况,通过回调函数network_event根据当前网络状况及时做出反应。

event_subscribe(EVENT_NETMGR_GOT_IP, network_event, NULL);
event_subscribe(EVENT_NETMGR_NET_DISCON, network_event, NULL);


为了达到每次开机不用手动输入SSID和密码的繁琐,可以利用YoC的partition(分区管理)和KV(Key-Value存储系统),将SSID和密码以键值对的方式保存在Flash中。


做好上述工作,便可以使我们的板子轻松连接到互联网中,连接后最习惯的操作就是ping一下。

1.png


确保ping通之后开始加入NTP功能。


YoC提供了两个组件ntp和sntp。看全称sntp的s代表的是simple,那就选择简单的入门,原想着快速达成功能,可这才是一波三折的开始……


第一次编译,系统提示我没有找到“sntp_setservername”函数。感觉被泼冷水一般,心想着官方的例子也会出错?抱着肯定是自己使用不当的态度,开始追源代码。发现这个sntp的simple和协议没多大关系,是直接调用了lwip的ntp的app。


好吧,看来是我没有加入lwip才导致的这个错误。手动添加lwip之后再次编译,噢吼,又有error。CDK告诉我,lwip的sys_init()这个函数被重复定义了。怎么可能?拿出八倍镜细细看了一下错误信息,原来是我手动添加的lwip之前,系统就有lwip这个组件了。


那么这个“罪魁祸首”是谁呢?SAL,Socket Adapter Layer。

在AliOS Things移植过程中,如果需要支持外接Wifi/BLE等模,且TCP/IP协议栈运行模组侧;
则需要SAL和底层模组控制模块进行对接。
SAL功能对上层提供标准socket接口,使上层应用不感知TCP/IP协议栈运行在MCU侧还是通讯模组侧。


那么对于RVB2601来说外挂的W800刚好属于运行了TCP/IP协议栈的通讯模组。可是SAL中并没有加入完整的lwip,那么现实就是对于RVB2601来说有SAL就没有SNTP,为了保住联网功能,只能放弃SNTP了。后来也咨询了OCC的技术小二,验证了这个想法。


幸好还有一条路,使用NTP组件。这次编译的过程倒是很顺,但是我依然不敢放松警惕。果不其然,还是出“幺蛾子”了:系统显示WiFi连接成功了,ping也通了,而且W800也完成了“doamin to IP”的解析,获取了服务器的实际IP,但是最后却告诉我时间同步失败了,见下图最后一行“NTP sync error”。

2.png


分析这段log发现,有一行“w800_dev conn_start fail”。就很纳闷,w800不是连接正常的吗。继续思考,对照W800的AT指令逐条分析,回想着基于UDP的NTP协议,发现驱动的一个Bug。


先说结论,这个Bug会导致所有基于UDP的网络请求连接失败。那么是什么导致这个Bug呢?w800_api.c这个文件的“w800_connect_remote”这个函数在发起UDP请求时的AT命令格式错误,正确的UDP AT命令应该是

id,udp_unicast,ip,remote_port,local_port


而驱动竟然是

id,udp_client,ip,remote_port


不仅把udp_unicast写成udp_client(只有tcp才有tcp_client),还漏写了local_port这个参数。


代码追到这里已经快到凌晨24点了,如果还是连接不上那我也只能放弃了。好在并没有其他的Bug出现,成功完成了NTP网络时间校准功能。

3.png


因为我们所属东八区,所以返回的时间需要加上8小时,才是正确时间。


总结,通过NTP协议完成了时间校准功能,并修复W800的AT命令Bug,使其能够建立正确的UDP连接。


本文源自:平头哥芯片开放社区

欢迎关注公众号:芯片开放社区(ID:OCC_THEAD),查看更多应用实战文章。

相关文章
|
7月前
|
算法 5G 网络性能优化
基于遗传优化的多属性判决5G-Wifi网络切换算法matlab仿真
基于遗传优化的多属性判决5G-Wifi网络切换算法matlab仿真
|
Ubuntu Linux
【Ubuntu18.04 解决蓝牙wifi 之ax201无线网卡驱动安装】
【Ubuntu18.04 解决蓝牙wifi 之ax201无线网卡驱动安装】
1827 0
|
5月前
|
Windows
Win10或Win11更新补丁后导致360随身wifi提示USB设备驱动异常,创建Wifi网络失败
Win10或Win11更新补丁后导致360随身wifi提示USB设备驱动异常,创建Wifi网络失败
960 0
|
Ubuntu Linux 芯片
linux系统中wifi驱动的配置与编译实现方法
linux系统中wifi驱动的配置与编译实现方法
746 1
【Matlab代码实现】电动过滤器:LPF和HPF、模拟调制:调幅和调频、WiFi、蓝牙和蜂窝网络的容量分析.....
【Matlab代码实现】电动过滤器:LPF和HPF、模拟调制:调幅和调频、WiFi、蓝牙和蜂窝网络的容量分析.....
137 0
修复WiFi网卡驱动异常导致WiFi图标消失报错代码(56)
修复WiFi网卡驱动异常导致WiFi图标消失报错代码(56)
【已解决】笔记本电脑连接wifi异常(无法连接到这个网络)
笔记本电脑连接wifi异常(无法连接到这个网络)
2040 1
【已解决】笔记本电脑连接wifi异常(无法连接到这个网络)
|
传感器 前端开发 算法
蓝牙、wifi、zigbee和lora、NB-lot,通话信号,网络信号4G
蓝牙、wifi、zigbee和lora、NB-lot,通话信号,网络信号4G
525 3
蓝牙、wifi、zigbee和lora、NB-lot,通话信号,网络信号4G
|
网络安全 Android开发 Windows
如何让手机共享电脑代理网络的WIFI热点
如何让手机共享电脑代理网络的WIFI热点
3715 0
如何让手机共享电脑代理网络的WIFI热点
|
Android开发
Android WIFI是否连接,网络状态监测工具类
Android WIFI是否连接,网络状态监测工具类
310 0