前言 想想自己为啥很长时间都没有写博客了,可能是写报告写的有点叛逆了,简称“恐报征”。本来就是自己做笔记,为啥为难自己呢?
关于这个板子 由于“信息系统设计”课程,老师定了一批全新的开发板,基本没有什么社区可以参考,除了厂家的一些样例程序,再无其他。可是这个板子搭载的也是STM32F407这样的高端处理器。总还是有一些高级的玩法。
由于前期不知道为啥Wifi模块自杀了,老师也给我换了新的,不过实在无法理解这个大而全的板子设计工程师的脑回路,全集成在一张板子上,可能是没有考虑到故障排除和维修的成本了,不过也可能是我多虑了,毕竟人家公司可是真金白银的花钱在研制了,再怎么说也总比拿钱去炒房有经济效益。
折腾MircoPython 实在是被这个辣鸡Wifi模块搞害怕了,直接基于模板开发容易陷入同质化的竞争,听了大佬的建议尝试一下用Python编写脚本,毕竟整点老师看不懂的东西容易博得欢心。
根据我搜索引擎专精的特性,解决问题分两步:找到一般解决方式;根据实际情况解决问题。
一般情况 直接搜索mircopython stm32移植
找到一些看着还算靠谱的博客,总结如下:
下载代码 —— 使用Git从Github仓库 上宕下来就好了
复制模板 —— 把ports/stm32/boards/STM32F4DISC
拷一份,作为模板修改
下载子模块 —— git submodule update --init
编译 —— WSL环境make
烧录 —— ST-Link
实际情况 毕竟这块板子非等闲之辈,怎么可能直接可以用呢?
针脚定义 各个阵脚的定义,到处全局搜索,查看需要定义的宏,还有就是可以使用的宏。分别定义好。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 #define MICROPY_HW_BOARD_NAME "DC-01" #define MICROPY_HW_MCU_NAME "STM32F407" #define MICROPY_HW_HAS_SWITCH (0) #define MICROPY_HW_HAS_FLASH (1) #define MICROPY_HW_ENABLE_RNG (1) #define MICROPY_HW_ENABLE_RTC (1) #define MICROPY_HW_ENABLE_DAC (1) #define MICROPY_HW_ENABLE_USB (0) #define MICROPY_HW_CLK_PLLM (8) #define MICROPY_HW_CLK_PLLN (336) #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2) #define MICROPY_HW_CLK_PLLQ (7) #define MICROPY_HW_UART1_TX (pin_A9) #define MICROPY_HW_UART1_RX (pin_A10) #define MICROPY_HW_UART3_TX (pin_B10) #define MICROPY_HW_UART3_RX (pin_B11) #define MICROPY_HW_UART4_TX (pin_C10) #define MICROPY_HW_UART4_RX (pin_C11) #define MICROPY_HW_UART5_TX (pin_C12) #define MICROPY_HW_UART5_RX (pin_D2) #define MICROPY_HW_UART6_TX (pin_C6) #define MICROPY_HW_UART6_RX (pin_C7) #define MICROPY_HW_UART_REPL PYB_UART_5 #define MICROPY_HW_UART_REPL_BAUD 115200 #define MICROPY_HW_SPI1_NSS (pin_A15) #define MICROPY_HW_SPI1_SCK (pin_B3) #define MICROPY_HW_SPI1_MISO (pin_B4) #define MICROPY_HW_SPI1_MOSI (pin_B5) #define MICROPY_HW_CAN1_TX (pin_A13) #define MICROPY_HW_CAN1_RX (pin_A12) #define MICROPY_HW_USRSW_PIN (pin_A0) #define MICROPY_HW_USRSW_PULL (GPIO_NOPULL) #define MICROPY_HW_USRSW_EXTI_MODE (GPIO_MODE_IT_RISING) #define MICROPY_HW_USRSW_PRESSED (1) #define MICROPY_HW_LED1 (pin_F9) #define MICROPY_HW_LED2 (pin_F10) #define MICROPY_HW_LED_ON(pin) (mp_hal_pin_low(pin)) #define MICROPY_HW_LED_OFF(pin) (mp_hal_pin_high(pin)) #define MICROPY_HW_USB_FS (MICROPY_HW_ENABLE_USB) #define MICROPY_HW_USB_MSC (0) #define MICROPY_HW_USB_HID (0) #define USBD_CDC_RX_DATA_SIZE (256) #define USBD_CDC_TX_DATA_SIZE (256) #define MICROPY_HW_BLE_UART_ID (PYB_UART_1) #define MICROPY_HW_BLE_UART_BAUDRATE (115200) #define MICROPY_HW_ETH_MDC (pin_C1) #define MICROPY_HW_ETH_MDIO (pin_A2) #define MICROPY_HW_ETH_RMII_REF_CLK (pin_A1) #define MICROPY_HW_ETH_RMII_CRS_DV (pin_A7) #define MICROPY_HW_ETH_RMII_RXD0 (pin_C4) #define MICROPY_HW_ETH_RMII_RXD1 (pin_C5) #define MICROPY_HW_ETH_RMII_TX_EN (pin_G11) #define MICROPY_HW_ETH_RMII_TXD0 (pin_G13) #define MICROPY_HW_ETH_RMII_TXD1 (pin_G14) #define MICROPY_HW_ETH_REST (pin_D3)
编译遇到如下问题:
1 2 3 4 5 6 7 8 9 10 eth.c:38:25: fatal error: lwip/etharp.h: No such file or directory #include "lwip/etharp.h" ^ compilation terminated. network_lan.c:34:24: fatal error: lwip/netif.h: No such file or directory #include "lwip/netif.h" ^ compilation terminated. ../../py/mkrules.mk:88: recipe for target 'build-HIBOARD/genhdr/qstr.i.last' failed
参照其他的开启了ETH的板子配置文件,得知由于没有启动这个库的编译开关,所以出错。在板子目录下的Makefile里添加MICROPY_PY_LWIP = 1
开启就可以了。
编译遇到如下问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 boards/HIBOARD/mpconfigboard.h:59:38: error: 'pin_F9' undeclared here (not in a function) #define MICROPY_HW_LED1 (pin_F9) ^ led.c:54:26: note: in expansion of macro 'MICROPY_HW_LED1' {{&pyb_led_type}, 1, MICROPY_HW_LED1}, ^~~~~~~~~~~~~~~ boards/HIBOARD/mpconfigboard.h:60:38: error: 'pin_F10' undeclared here (not in a function) #define MICROPY_HW_LED2 (pin_F10) ^ led.c:56:26: note: in expansion of macro 'MICROPY_HW_LED2' {{&pyb_led_type}, 2, MICROPY_HW_LED2}, ^~~~~~~~~~~~~~~ ../../py/mkrules.mk:63: recipe for target 'build-HIBOARD/led.o' failed make: *** [build-HIBOARD/led.o] Error 1
反过头去了解了一下,发现针脚需要先在pins.csv
里定义,遂全部按照PA1
这样定义,后发现可以重复定义,把一些特殊的GPIO定义上特殊的名字,问题解决。
再次编译,有遇到如如下问题:
1 2 3 4 5 6 7 8 9 10 11 12 build-HIBOARD/frozen_content.c:137:5: error: redeclaration of enumerator 'MP_QSTR_SOL_SOCKET' MP_QSTR_SOL_SOCKET, ^~~~~~~~~~~~~~~~~~ In file included from ../../py/obj.h:33:0, from ../../py/objint.h:30, from build-HIBOARD/frozen_content.c:15: build-HIBOARD/genhdr/qstrdefs.generated.h:834:6: note: previous definition of 'MP_QSTR_SOL_SOCKET' was here QDEF(MP_QSTR_SOL_SOCKET, (const byte*)"\x0f\xdf\x0a" "SOL_SOCKET") ^ ../../py/qstr.h:41:23: note: in definition of macro 'QDEF' #define QDEF(id, str) id,
然后去看了build-HIBOARD/genhdr/qstrdefs.generated.h
发现并没有这一行代码,遇事不决清一波缓存,问题解决。
至此,编译成功。
以太网模块适配 上版测试后发现,以太网模块无法驱动,对照其他的官方支持板子的电路图,查看接线区别。发现一根本来应该使用硬件控制的,日常拉高的重置接口,在这个板子上直接接到了GPIO的一个口。
为了发现这个错误可以说是煞费苦心了,在MicroPython代码中添加调试输出,疯狂参照官方给的Rj45使用样例的逻辑修改模块,对照着令人眼瞎的接线图,发现了这一个需要拉高的操作。
修改ports\stm32\eth.c
文件,在eth_mac_init
函数的开始添加拉高操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #ifdef MICROPY_HW_ETH_REST GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Pin = MICROPY_HW_ETH_REST->pin_mask; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; HAL_GPIO_Init(MICROPY_HW_ETH_REST->gpio, &GPIO_InitStructure); mp_hal_pin_low(MICROPY_HW_ETH_REST); mp_hal_delay_ms(50); mp_hal_pin_high(MICROPY_HW_ETH_REST); #endif
成功点亮以太网接口。
其他模块 告辞,又不是不能用,虽然没定义了蓝牙的接口,还没时间搞。
最终结果 使用ampy
这个工具上传http_server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 try : import usocket as socket except : import socket from network import LANCONTENT = b"""\ HTTP/1.0 200 OK Hello #%d from MicroPython! """ def main (micropython_optimize=False ): l = LAN() l.active(1 ) l.ifconfig(('192.168.0.4' , '255.255.255.0' , '192.168.0.1' , '8.8.8.8' )) s = socket.socket() ai = socket.getaddrinfo("0.0.0.0" , 8080 ) print("Bind address info:" , ai) addr = ai[0 ][-1 ] s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 ) s.bind(addr) s.listen(5 ) print("Listening, connect your browser to http://<this_host>:8080/" ) counter = 0 while True : res = s.accept() client_sock = res[0 ] client_addr = res[1 ] print("Client address:" , client_addr) print("Client socket:" , client_sock) client_stream = client_sock.makefile("rwb" ) print("Request:" ) req = client_stream.readline() print(req) while True : h = client_stream.readline() if h == b"" or h == b"\r\n" : break print(h) client_stream.write(CONTENT % counter) client_stream.close() client_sock.close() counter += 1 print() main()
访问http://192.168.0.4:8080
得到结果:
我觉得单凭这一块就可以交差了。
结尾 这个板子售价950+,买点就是“我们板子一应俱全”,感觉设计板子的人可能是这门课老师的学生,设计的板子和老师的报告有异曲同工之妙。