移植micropython最小工程到mm32f3270微控制器(2)-增加MM32的移植

391 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

移植micropython最小工程到mm32f3270微控制器(2)

增加MM32的移植

从MM32 SDK中提取ARMGCC版本的MM32F3270的相关源码文件, 包含芯片头文件、启动汇编文件、设备驱动源文件, 以及一个简单的BSP(board_init.c, pin_init.c和clock_init.c). 集成到micropython之前, 先原地build一下, 确保代码无误.

  1. 向lib目录下新建"mm32"目录, 添加平台级的代码, 包括芯片头文件、启动汇编文件、设备驱动源文件, 同时要为以后新增其它MM32微控制器芯片支持文件预留位置. 并且直接使用lib自带的cmsis目录, 不再另外添加MM32 SDK中的CMSIS.

figure_mpy_lib_mm32.png

  1. 在ports目录下新建"mm32"目录, 在"mm32"目录下创建"boards"目录, 在"boards"目录下创建"MB_F3270"目录.

figure_mpy_ports_mm32.png

这里特别讲一下这些文件的功能:

  • "ports/mm32/boards/MB_F3270"目录下的文件(board_init、pin_init、clock_init)直接来自于MM32 SDK样例工程, 主要实现BOARD_Init()函数, 用以对芯片的系统时钟和通信UART串口初始化.
  • 新增的"mpconfigboard.h"文件, 是按照micropython的移植规范添加的, 但其实在里面仅仅定义了板子和芯片的名字.
#define MICROPY_HW_BOARD_NAME "MB_F3270"
#define MICROPY_HW_MCU_NAME   "MM32F3277G7P"
  • 新增的"mpconfigboard.mk"文件, 指定了芯片的系列, 型号, 以及链接命令文件相对于"ports/mm32"目录的位置.
  • "ports/mm32/boards"目录下放置了链接命令文件, 放在这里的意义在于, 它可以被多个使用相同芯片的不同板子引用. 若以后还有不同的芯片, 或者相同芯片的不同链接配置, 都可以放在同级目录下, 供更多的板子引用.
  • "ports/mm32"根目录下的"mpconfigport.h", 是直接从SAMD的移植中复制过来的,是对py核心的裁剪. 之前的移植都是从minimal或者mimxrt中拿过来,但现在minimal已阵亡,mimxrt也已经变得庞大,不适合用来做最小工程。
  • "ports/mm32"根目录下的"qstrdefsport.h", 也是直接从SAMD的移植中复制过来的, 这个文件将被用于在build之前传入python脚本用于自动生成关键字清单的, 移植的时候别动它, 让makefile照例处理。这个文件里面实际是空的,但是保存了给后期字符串处理的标签.
// qstrs specific to this port
// *FORMAT-OFF*
  • "mphalport.h"和"mphalport.c"顾名思义是micropython系统对硬件平台提出的移植需求. 目前主要在mphalport.c中实现了串口终端到硬件平台的重映射, mphalport.h用内联函数的方式实现定时器的底层函数. 实际上, micropython最小工程中还应该包含一个核心模块utimer, 做定时器用的, 可以在这里简单支持一下(基于Systic即可). 但我为了精简, 竟然连这个模块也给移除了,真的是能简尽简了. 在此处, 对定时器底层的实现都是空的.

"mphalport.c"文件内容如下:

#include "py/runtime.h"
#include "py/stream.h"
#include "py/mphal.h"#include "board_init.h"
#include "hal_uart.h"int mp_hal_stdin_rx_chr(void)
{
    while ( 0u == (UART_STATUS_RX_DONE & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
    {}
    return UART_GetData(BOARD_DEBUG_UART_PORT);
}
​
void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len)
{
    while (len--)
    {
        while ( 0u == (UART_STATUS_TX_EMPTY & UART_GetStatus(BOARD_DEBUG_UART_PORT)) )
        {}
        UART_PutData(BOARD_DEBUG_UART_PORT, *str++);
    }
}
​
/* EOF. */

"mphalport.h"内容如下:

static inline mp_uint_t mp_hal_ticks_ms(void) {
    return 0;
}
static inline void mp_hal_set_interrupt_char(char c) {
}
​
  • "modmachine.c", 这个文件里, 是实现micropyhton中"machine"模块的根类, 就是可以import的模块. 原型文件来自于MIMXRT的移植, 但我为了简化, 减少不必要的麻烦, 仅剩下了"machine"类的定义.
#include "py/runtime.h"
#include "py/obj.h"
#include "extmod/machine_mem.h"
​
//STATIC mp_obj_t machine_reset(void) {
//    NVIC_SystemReset();
//    return mp_const_none;
//}
//MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
​
STATIC mp_obj_t machine_freq(void) {
    //return MP_OBJ_NEW_SMALL_INT(CLOCK_GetFreq(kCLOCK_CpuClk));
    return MP_OBJ_NEW_SMALL_INT(96000000);
}
MP_DEFINE_CONST_FUN_OBJ_0(machine_freq_obj, machine_freq);
​
STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
    { MP_ROM_QSTR(MP_QSTR___name__),            MP_ROM_QSTR(MP_QSTR_umachine) },
//    { MP_ROM_QSTR(MP_QSTR_reset),               MP_ROM_PTR(&machine_reset_obj) },
    { MP_ROM_QSTR(MP_QSTR_freq),                MP_ROM_PTR(&machine_freq_obj) },
    { MP_ROM_QSTR(MP_QSTR_mem8),                MP_ROM_PTR(&machine_mem8_obj) },
    { MP_ROM_QSTR(MP_QSTR_mem16),               MP_ROM_PTR(&machine_mem16_obj) },
    { MP_ROM_QSTR(MP_QSTR_mem32),               MP_ROM_PTR(&machine_mem32_obj) },
};
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
​
const mp_obj_module_t mp_module_machine = {
    .base = { &mp_type_module },
    .globals = (mp_obj_dict_t *)&machine_module_globals,
};
​
  • "main.c"是顶级应用, 程序入口. 之前mimxrt的移植是比较简单的, 但仍有pyexec_frozen_module()函数的调用. 现在看SAMD的移植比较清爽, 所以这次直接从SAMD的移植拿来. 去掉关于tusb的部分, 在main()函数里最开始的位置插入"BOARD_Init()", 调用函数对具体板子进行初始化.
  • "Makefile". Makefile是整个移植过程中最耽误时间的, 我曾经花费了很多时间想把makefile改成可视化的keil或者iar工程, 至少是方便阅读的CMakeLists.txt也行啊. 奈何我对Makefile的各种灵活用法实在搞不定, 所以还是老老实实改. SAMD的Makefile写得还是很清爽的, 之前MIMXRT也曾经清爽过, 但现在已经开始变得庞大了. 关于Makefile, 实在需要一整章来说明.

(未完待续。。。)