NUCLEO-F767ZI以太网功能实现笔记本电脑不开盖开机
来源:互联网 发布:mac 资料库在哪 编辑:程序博客网 时间:2024/05/16 08:44
NUCLEO-F767ZI以太网功能实现笔记本电脑不开盖开机
不想打开笔记本盖子按开机按钮开机?可以使用Wake-on-LAN远程唤醒。这里展示怎么用NUCELO-F767ZI以太网功能发送MagicPacket唤醒笔记本电脑。
http://blog.csdn.net/zoomdy/article/details/54799462
mingdu.zheng at gmail dot com
缘起:不想开盖按电源按钮
因为有一台23吋显示器,笔记本电脑在家里基本上当台式机用。每次开机的时候都要打开翻盖按一下电源按钮然后又合上,嫌开盖开机麻烦,然后就在网上找不开盖就能开机的方法,唯一靠谱的方案就是Wake-on-LAN,即局域网唤醒,简称WOL。正好有一块NUCLEO-F767ZI开发板,这是一款带以太网的开发板,可以用来发送MagicPacket唤醒我的笔记本电脑。
设置BIOS
要使用Wake-on-LAN功能,首先要进入BIOS打开Wake-on-LAN功能,不同的机器其设置位置可能不同,进BIOS找一找。也有可能不被支持。
验证Wake-on-LAN可以工作
这里以Ubuntu 12.04为例,Windows环境可以问度娘。首先使用ethtool工具检查需要被唤醒的机器是否正确打开了Wake-on-LAN功能,请注意ethtool工具输出的两条信息 Supports Wake-on: pumbg 和 Wake-on: g,Supports Wake-on说明是否具备Wake-on-LAN功能,Wake-on为g说明已经打开了Wake-on-LAN,如果Wake-on为d说明Wake-on-LAN被关闭了,更具体的内容可以 man ethtool。
sudo apt-get install ethtoolsudo ethtool eth0
Settings for eth0: ...... Supports Wake-on: pumbg Wake-on: g
关闭需要被唤醒的机器,然后在另外一台电脑使用wakeonlan工具唤醒。
sudo apt-get install wakeonlanwakeonlan 28:D2:44:3E:07:56
Sending magic packet to 255.255.255.255:9 with 28:D2:44:3E:07:56
如果设置没有错的话,稍等几秒钟就可以看到机器被唤醒了。
唤醒的原理
wakeonlan命令会发送一个目标端口为9的UDP广播数据包:MagicPacket,待唤醒机器的网卡接收到MagicPacket后,就会唤醒计算机。MagicPacket的格式如下图所示,开头是6字节FF,后面复制16份待唤醒机器的MAC地址。
关于Wake-on-LAN更详细的内容可以参考这里:https://wiki.wireshark.org/WakeOnLAN
用NUCLEO-F767ZI实现唤醒
如果要用另外一台电脑输入命令来唤醒我的笔记本电脑,那比开盖更麻烦啊!我的预期是:按下排插按钮就可以自动唤醒。正好我有一块NUCLEO-F767ZI开发板,这是一块带有以太网功能的开发板,可以用NUCLEO-F767ZI发送MagicPacket唤醒机器。
首先参考这篇http://blog.csdn.net/zoomdy/article/details/54784027将以太网功能跑通。
然后修改lwIP配置,使用静态地址方式,DHCP获取地址是需要时间的,静态地址可以快很多。
编写代码,在NUCLEO-F767ZI上电后发送一个MagicPacket,这是一个UDP包,使用lwIP的udp_*系列API来实现。没有使用socket接口,也没有加入FreeRTOS,这是个简单的应用,简单一些就可以了。
完整的源代码请访问:https://git.oschina.net/zoomdy/Wake-on-LAN,这里给出关键代码。
/* * Src/wol.c * https://wiki.wireshark.org/WakeOnLAN * * Packet Format * |Synchronization Stream |Target MAC |Password (optional) | * |6 |96 |0, 4 or 6 | * * The Synchronization Stream is defined as 6 bytes of FFh. * * The Target MAC block contains 16 duplications of the IEEE address * of the target, with no breaks or interruptions. * * The Password field is optional, but if present, contains either 4 * bytes or 6 bytes. The WakeOnLAN dissector was implemented to dissect * the password, if present, according to the command-line format that * ether-wake uses, therefore, if a 4-byte password is present, it will * be dissected as an IPv4 address and if a 6-byte password is present, * it will be dissected as an Ethernet address. */#include <stdint.h>#include <string.h>#include "stm32f7xx_hal.h"#include "lwip.h"#include "lwip/udp.h"#include "wol.h"void Error_Handler(void);// 被唤醒机器的MAC地址static const uint8_t targetAddress[ETHARP_HWADDR_LEN] = { 0x28, 0xd2, 0x44, 0x3e, 0x07, 0x56 };static void fillMagicPacket(uint8_t buf[]){ int i; memset(&buf[0], 0xff, ETHARP_HWADDR_LEN); for (i = 0; i < 16; i++) { memcpy(&buf[(1 + i) * ETHARP_HWADDR_LEN], &targetAddress[0], ETHARP_HWADDR_LEN); }}static void sendMagicPacket(void){ static struct udp_pcb *pcb = NULL; struct pbuf *pbuf = NULL; err_t err; if (pcb == NULL) { pcb = udp_new(); if (pcb == NULL) { Error_Handler(); } err = udp_connect(pcb, IP_ADDR_BROADCAST, 9); if (err != ERR_OK) { Error_Handler(); } } pbuf = pbuf_alloc(PBUF_TRANSPORT, (1 + 16) * ETHARP_HWADDR_LEN, PBUF_RAM); if (pbuf == NULL) { Error_Handler(); } fillMagicPacket(pbuf->payload); err = udp_send(pcb, pbuf); if (err != ERR_OK) { Error_Handler(); } pbuf_free(pbuf); pbuf = NULL;#if 0 // 不要释放pcb,后面还要用 udp_remove(pcb); pcb = NULL;#endif}void WOL_Process(void){ static int fired = 0; uint32_t tick; tick = HAL_GetTick(); if(fired == 0 && tick >= 2000) // 上电2秒后发送Magic Packet { sendMagicPacket(); HAL_GPIO_WritePin(GPIOB, LED_RED_Pin, GPIO_PIN_SET); fired = 1; }}void BTN_Process(void){ static uint32_t tick_prev = 0; static uint32_t btn_state = 0; uint32_t tick; tick = HAL_GetTick(); if(tick != tick_prev) { tick_prev = tick; btn_state <<= 1; if(HAL_GPIO_ReadPin(BTN_USER_GPIO_Port, BTN_USER_Pin)) { btn_state |= 1; HAL_GPIO_WritePin(GPIOB, LED_BLUE_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GPIOB, LED_RED_Pin, GPIO_PIN_RESET); } else { btn_state |= 0; HAL_GPIO_WritePin(GPIOB, LED_BLUE_Pin, GPIO_PIN_RESET); } if(btn_state == 0xffff0000) // 按钮释放立即发送Magic Packet { sendMagicPacket(); HAL_GPIO_WritePin(GPIOB, LED_RED_Pin, GPIO_PIN_SET); } }}void LED_Process(void){ if(HAL_GetTick() & 0x100) { HAL_GPIO_WritePin(GPIOB, LED_GREEN_Pin, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(GPIOB, LED_GREEN_Pin, GPIO_PIN_RESET); }}
/* * Src/main.c 仅给出main函数部分 */int main(void){ /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration----------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART3_UART_Init(); MX_LWIP_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ MX_LWIP_Process(); WOL_Process(); BTN_Process(); LED_Process(); __WFE(); // Save 40mA } /* USER CODE END 3 */}
最后
用NUCLEO-F767ZI做这么简单的工作是不是大材小用了?过了元宵节,买块NUCLEO-F207ZG,终于有理由买NUCLEO-F207ZG了。:)
- NUCLEO-F767ZI以太网功能实现笔记本电脑不开盖开机
- NUCLEO-F767ZI以太网初探
- 手机实现远程开机功能
- 清除笔记本电脑开机密码攻略
- 笔记本电脑忘记开机密码怎么办?
- 如何提高笔记本电脑开机速度
- 以太网实现
- 看WIZ110SR如何实现串口转以太网功能
- android 4.4 以太网网络共享功能研究和实现
- 关于睡眠唤醒实现开机功能
- 跨VLAN远程开机功能实现
- java程序实现开机自启动功能
- Windows下C++开机启动功能实现
- 笔记本电脑开启无线网络连接功能
- 昭阳M10笔记本电脑开机黑屏处理方法
- 转:笔记本电脑开机密码忘记的解决方法
- 怎么样给笔记本电脑设置开机密码
- 华硕笔记本电脑开机蓝屏怎么解决
- 假期学习之XML和Json 篇
- zoneminder报警(微信、QQ提醒)
- json
- sdnu 1010
- ubuntu14.04 安装 kdbg 以及运行 kdbg 遇到的问题
- NUCLEO-F767ZI以太网功能实现笔记本电脑不开盖开机
- Constructing Roads
- 马踏棋盘算法(骑士周游问题)
- [bzoj3956] Count
- 1小时学会:最简单的iOS直播推流(一)介绍
- SAP HR模块的基础数据表和增强配置
- VS2010开发的WPF程序在XP系统上的运行环境和lognet4在WPF中的配置使用
- sdnu 1009
- 多媒体篡改检测资源