本项目受qinyunti大牛的启发很深,比如shell下先调通wav文件播放,然后把micropython作为shell的一个子命令实现等等,甚至很多源码直接来自大牛的开源的代码仓库:https://gitee.com/qinyunti/fr3068-e-c-micropython.git


一.初步nr_micro_shell工程
建立mpy工程目录:
mkdir examples/evb_demo/mpy/
  • mkdir examples/evb_demo/mpy/Src
  • mkdir examples/evb_demo/mpy/Inc
  • 复制代码


    copy lvgl_demo的一些头文件/源文件到examples/evb_demo/mpy/Inc或Src目录:
    cp examples/evb_demo/lvgl_demo/Inc/app_config.h examples/evb_demo/mpy/Inc
  • cp examples/evb_demo/lvgl_demo/Inc/FreeRTOSConfig.h examples/evb_demo/mpy/Inc
  • cp examples/evb_demo/lvgl_demo/Src/main.c examples/evb_demo/mpy/Src
  • cp examples/evb_demo/lvgl_demo/Src/app_task.c examples/evb_demo/mpy/Src
  • cp examples/evb_demo/lvgl_demo/Src/app_hw* examples/evb_demo/mpy/Src
  • 复制代码


    下载nr_micro_shell源码:
    因笔者比较熟悉nr_micro_shell,所以shell是用的nr_micro_shell。从github上下载nr_micro_shell后,把它的inc和src目录下的文件copy到examples/evb_demo/mpy/nr_micro_shell下。

    改写main()函数
    主要是初始化nr_micro_shell、创建shell任务和rx_queue消息队列,shell任务主要是读rx_queue消息队列然后执行nr_micro_shell的shell()函数;rx_queue用于从串口接收数据发送给shell任务

    改写void uart3_irq()函数
    使得它在INT_INDEX_RX或INT_INDEX_RX_TOUT置位时,读取UARTx->DATA_DLL.DATA,然后调用xQueueSendFromISR()函数把获得的字符发送给rx_queue队列


    现在nr_micro_shell框架基本做好,再用nr_micro_shell的方式实现md和mw命令,md从地址读,mw往地址写

    编译烧录后,运行截图如下
    2.jpg
    从图中我们可以看到,0x2007fffc这个地址写入后读取确实能读到写入的值,说明板子的MCU确实是512KB的sram。


    二.接下来我们继续移植micropython


    从qinyunti大牛的仓库examples/evb_demo/lvgl_demo下复制文件过来:

    cp PATH_TO_qinyuti_repo/examples/evb_demo/lvgl_demo/Src/app_dac* examples/evb_demo/mpy/Src
  • cp PATH_TO_qinyuti_repo/examples/evb_demo/lvgl_demo/Src/app_micropython* examples/evb_demo/mpy/Src
  • cp PATH_TO_qinyuti_repo/examples/evb_demo/lvgl_demo/Src/wav_decode* examples/evb_demo/mpy/Src
  • cp PATH_TO_qinyuti_repo/examples/evb_demo/lvgl_demo/Src/wav_decode* examples/evb_demo/mpy/Src
  • cp -a PATH_TO_qinyuti_repo/examples/evb_demo/lvgl_demo/Src/py examples/evb_demo/mpy/Src
  • cp -a PATH_TO_qinyuti_repo/examples/evb_demo/lvgl_demo/Src/py_port examples/evb_demo/mpy/Src
  • 复制代码
    注:一般来说micropython编译过程中需要配置下,但qinyunti大牛已经帮我们把micropython配置好了,所以沿用即可。

    拷贝完毕的mpy/Src目录如下
    3.jpg

    添加micropython命令
    按nr_micro_shell方式添加micropython命令,调用py_main()函数即可。

    修改py_port/uart_core.c的mp_hal_stdin_rx_chr()函数
    使得它和上面shell任务一样,从rx_queue消息队列获得uart输入数据。

    copy大牛的spi flash补丁等
    把qinyunti大牛打过patch的spi_flash拷贝过来,这在他的帖子都提到了,到相应目录下拷贝覆盖即可。
    把qinyunti大牛shell下的ymodem.[ch]拷贝过来,并拷贝ryfile实现,这个命令主要用来从pc机上传wav文件到板子flash。除此以外还需要修改main.c,一样的做mount,如失败先mkfs再mount尝试等动作。

    最后笔者的CMakeLists.txt文件如下:
    set(CMAKE_SYSTEM_NAME Generic)
  • set(CMAKE_SYSTEM_VERSION 1)
  • set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
  • cmake_minimum_required(VERSION 3.20)

  • set(CMAKE_C_COMPILER arm-none-eabi-gcc)
  • set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
  • set(CMAKE_ASM_COMPILER arm-none-eabi-gcc)
  • set(CMAKE_AR arm-none-eabi-ar)
  • set(CMAKE_OBJCOPY arm-none-eabi-objcopy)
  • set(CMAKE_OBJDUMP arm-none-eabi-objdump)
  • set(SIZE arm-none-eabi-size)

  • set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
  • set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
  • set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
  • set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

  • add_compile_options(-pipe -mthumb -mcpu=star-mc1 -mfloat-abi=hard -mfpu=fpv5-sp-d16)
  • add_compile_options(-fno-builtin -ffreestanding -ffunction-sections -fdata-sections -fno-builtin -fno-common -Wall -Wshadow -Wdouble-promotion -Wno-unused-parameter)

  • add_compile_options(-O3)

  • project(fr30xxc C ASM)
  • set(CMAKE_CXX_STANDARD 11)
  • set(CMAKE_C_STANDARD 99)

  • include_directories(components/btdm/include
  •                     components/drivers/cmsis
  •                     components/drivers/device
  •                     components/drivers/device/fr30xx
  •                     components/drivers/peripheral/Inc
  •                     components/drivers/bsp/spi_flash
  •                     components/modules/common/include
  •                     components/modules/crc
  •                     components/modules/FreeRTOS/include
  •                     components/modules/FreeRTOS/portable/ARMv8M/non_secure
  •                     components/modules/FreeRTOS/portable/ARMv8M/non_secure/portable
  •                     components/modules/FreeRTOS/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ
  •                     components/modules/heap
  •                     components/modules/audio
  •                     components/modules/audio/codec
  •                     components/modules/audio/resample
  •                     components/modules/fatfs/source
  •                     examples/evb_demo/mpy/Inc
  •                     examples/evb_demo/mpy/Src
  •                     examples/evb_demo/mpy/Src/nr_micro_shell
  •                     examples/evb_demo/mpy/Src/py_port
  •                     examples/evb_demo/mpy/Src/py
  •                     )

  • add_definitions(-DUSE_STDPERIPH_DRIVER)

  • file(GLOB_RECURSE SOURCES
  •                 "components/drivers/device/fr30xx/*.c"
  •                 "components/drivers/device/fr30xx/gcc/*.c"
  •                 "components/drivers/device/fr30xx/gcc/startup_fr30xx.S"
  •                 "components/drivers/peripheral/Src/*.c"
  •                 "components/drivers/bsp/spi_flash/*.c"
  •                 "components/modules/common/src/*.c"
  •                 "components/modules/crc/crc32.c"
  •                 "components/modules/fatfs/source/*.c"
  •                 "components/modules/FreeRTOS/portable/ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.c"
  •                 "components/modules/FreeRTOS/portable/ARMv8M/non_secure/port.c"
  •                 "components/modules/FreeRTOS/portable/MemMang/heap_6.c"
  •                 "components/modules/FreeRTOS/croutine.c"
  •                 "components/modules/FreeRTOS/event_groups.c"
  •                 "components/modules/FreeRTOS/freertos_sleep.c"
  •                 "components/modules/FreeRTOS/list.c"
  •                 "components/modules/FreeRTOS/queue.c"
  •                 "components/modules/FreeRTOS/stream_buffer.c"
  •                 "components/modules/FreeRTOS/tasks.c"
  •                 "components/modules/FreeRTOS/timers.c"
  •                 "components/modules/FreeRTOS/cpu_context_gcc.S"
  •                 "components/modules/heap/heap.c"
  •                 "examples/evb_demo/mpy/Src/*.c"
  •                 )

  • set(LINKER_SCRIPT ${CMAKE_SOURCE_DIR}/components/tools/gcc/ldscript.ld)
  • add_link_options(
  •                 -mthumb -mcpu=star-mc1 -mfloat-abi=hard -mfpu=fpv5-sp-d16
  •                 -Wl,--gc-sections,--print-memory-usage,-Map,${PROJECT_NAME}.map
  •                 --specs=nano.specs
  •                 --specs=nosys.specs
  •                 )
  • add_link_options(-T ${LINKER_SCRIPT})

  • add_executable(${PROJECT_NAME}.elf ${SOURCES} ${LINKER_SCRIPT})

  • target_link_libraries(${PROJECT_NAME}.elf m)

  • set(HEX_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.hex)
  • set(BIN_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.bin)
  • set(LST_FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}.lst)
  • add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD
  •         COMMAND ${CMAKE_OBJCOPY} -Oihex [        DISCUZ_CODE_345        ]amp;lt;TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE}
  •         COMMAND ${CMAKE_OBJCOPY} -Obinary [        DISCUZ_CODE_345        ]amp;lt;TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE}
  •         COMMAND ${CMAKE_OBJDUMP} --all-headers --demangle --disassemble [        DISCUZ_CODE_345        ]amp;lt;TARGET_FILE:${PROJECT_NAME}.elf> > ${LST_FILE}
  •         COMMAND ${SIZE} --format=berkeley [        DISCUZ_CODE_345        ]amp;lt;TARGET_FILE:${PROJECT_NAME}.elf>
  •         COMMAND python3 ${CMAKE_SOURCE_DIR}/components/tools/post_process.py ${PROJECT_NAME} .
  • )
  • z
  • 复制代码


    编译
    <pre>cmake -B /tmp/build
  • cmake --build /tmp/build -j8</pre>
  • 复制代码
    1.jpg

    接上喇叭
    笔者是从一个巧克力礼盒上拆了一个喇叭出来,杜邦线一段剖开焊上,另一端接板子的spk口。

    214332981.jpg

    运行截图
    先运行rfile,然后minicom下通过ymodem传个wav文件:

    y1.jpg
    y2.jpg

    上传完毕,ls看看
    5.jpg

    现在可以执行micropython命令啦,进micropython REPL后依次执行
    import pyb
  • audio = pyb.AUDIO(1)
  • audio.play("2:/haikuotiankong.wav")
  • 复制代码
    喇叭就能有声音了。

    笔者执行micropython截图如下:
    6.jpg


    三.总结与展望:
    由arm中国的star-mc1加持的FR3068E-C很强,坊间传闻star-mc1和cortex-m33不相上下。除flash烧录外,笔者成功搭建了在linux下开发FR3068E-C开发环境,并写出了可复用的CMakeLists.txt模板。然后在qinyunti大牛的指引下,笔者也顺利完成microPython本地音乐播放。后续笔者还想继续完成openocd
    的flash写支持,从而完全脱离windows操作系统的依赖,完整实现linux下的开发环境。

    最后对厂商的建议:
    1.开发板出厂固件前面能否加个延时1s左右再改引脚复用功能,方便swd连接
    2.强烈建议出MCU对应的pack包,方便pyocd使用
    3.下一个板子能否支持调试口供电,这样不用插两个usb接口