Skip to content

Micopython

https://blog.csdn.net/jd3096/article/details/120641783

这里以micropython1.16为例 git之后,找到micropython\drivers目录,新建一个自己的文件夹,比如cs 然后找到ports\esp32\boards目录下,找到manifest.py文件,参照默认的格式加入自己需要的py文件后编译固件即可,这下再也不用现拷贝各种Py库了,固件刷完了直接import即可,而且别人还看不到你py文件的内容,岂不美哉?

struct

https://docs.python.org/3.5/library/struct.html#module-struct

ulab

https://micropython-ulab.readthedocs.io/en/latest/numpy-functions.html

ESPIDF使用

下载完ESP-IDF后,利用 idf.py build 或者 flash,对于windows和Linux是一样的 windows 下记得手动运行 install.bat

  • windows下
    • 编译 idf.py build

    • 指定开发板idf.py set-target esp32s3

      • 指定后会多四个文件
      • alt text
    • 烧录idf.py -p PORT flash -p是port的意思

    • 串口idf.py -p PORT monitor 查看消息,使用快捷键 Ctrl+],可退出 ESP-IDF 监视器。

    • 上述内容的综合idf.py -p PORT flash monitor

    • 配置工具idf.py menuconfig,如从规格书查看Flash和PSRAM的接口,从规格书看到N16R8的flash使用Quad SPI,PSRAM使用Octal SPI,flash选择16MB

新建工程

  • idf.py create-project PROJECT_NAME

  • 使用示例 idf.py create-project-from-example "espressif/usb_stream=*:usb_camera_mic_spk"

使用 ESP-IoT-Solution 组件

  • 添加 IOT_SOLUTION_PATH 环境变量: set IOT_SOLUTION_PATH=F:\ESP32\ESPIDF\esp-iot-solution

idf.py add-dependency "espressif/usb_stream

CDC HID VCP驱动对比

文件结构

主要的文件结构就是 main 和一个 cmakelist.txt

c
/**mian中 */
idf_component_register(SRCS "hello_world_main.c"
                    INCLUDE_DIRS "")

/**main外 */
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(hello_world)

main 下面的结构 idf_component.yml 是依赖结构,如果执行idf.py add-dependency "espressif/usb_stream^1.4.0",则会自动添加yml配置。idf.py set-target esp32s3后就会新建 managed_components 文件下,里面是依赖的组件

sdkconfig 里面是 menuconfig里可以更改的常量

硬件设计

对于ESP32S3硬件而言,ESP32-S3-Korvo2-V3 是可借鉴的比较全面的方案
https://espressif-docs.readthedocs-hosted.com/projects/esp-adf/zh-cn/latest/design-guide/dev-boards/user-guide-esp32-s3-korvo-2.html

HCD MPS

  • 在USB通信中,"HCD DWC: EP MPS"通常指的是USB主机控制器驱动(Host Controller Driver, HCD)在使用DWC(DesignWare Core)USB OTG控制器时,与特定端点(Endpoint, EP)的最大包大小(Maximum Packet Size, MPS)相关的概念。一个全速(Full-speed)USB设备的端点MPS通常是64字节
  • 请注意,MPS(最大包大小)是在USB通信中定义的,它指定了在高带宽ISO传输中,端点可以在一个服务间隔中发送或接收的最大数据量。在配置UAC流时,确保缓冲区大小符合连接的USB设备的能力。
c
I (1320) USB_STREAM: Speaker Interface found, interface = 2
I (1321) USB_STREAM:    Endpoint(ISOC) Addr = 0x1, MPS = 384
I (1321) USB_STREAM:    Speaker frequency control  Support
I (1321) USB_STREAM: Mic Interface found interface = 1
I (1322) USB_STREAM:    Endpoint(ISOC) Addr = 0x81, MPS = 96
I (1322) USB_STREAM:    Mic frequency control  Support

一些小知识

在Windows操作系统中,一个URB一般包含10ms的数据内容(960字节),即每URB的数据为10个ISO同步包 USB等时传输通常在一个USB帧内传输数据,而USB帧的间隔为1毫秒。因此,每帧需要传输的数据量为: 192000字节/秒 /1000毫秒/秒 = 192字节/毫秒

如果USB设备支持的MPS(最大包大小)为128字节,那么每帧需要的包数量为: 192字节/毫秒 / 128字节/包 = 1.5包/毫秒

alt text

没想到杰理的文档居然从深圳云信通讯技术有限公司获取的到http://www.yunthinker.com/down.html

CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=8192 设置了一个大小阈值,用于控制分配内存时优先选择内部存储器还是外部存储器(PSRAM)。如果分配的空间小于或等于这个阈值,内存分配程序将首先选择内部存储器512K=64000B SRAM。如果分配的空间大于阈值,分配程序将首先选择外部存储器8M SPI SRAM。如果在优先考虑的内部或外部存储器中没有可用的存储块,分配程序则会选择其他类型存储。

任务堆栈、DMA等只会分配在片内RAM中。片外RAM访问大块数据时(大于 32 KB)会导致速度下降。

esp32 配置

flash用SQI速度最快。USB-OTG的FIFO SIZE需要正确调节。 hal usb_dwc_hal.c经过修改
对ESP32S3 总的硬件FIFO 等效的Line 为 198(792 bytes) 推荐的配置为 ————> 16(64 bytes) np-T , 96(384 byets) p-T , 84+2(336 bytes) R
idf_component.yml 中的内容添加 usb_host_uac: "1.0.*" main.c 中需要把usb device功能关闭 CONFIG_USB_HOST_CONTROL_TRANSFER_MAX_SIZE=2048 这个值默认是256会出bug

KT0120 的16bit Speaker 需要 Max Packet Size 384(96), 24bit Speaker 需要 Max Packet Size 576(144) 。16bit Microphone 需要 Max Packet Size 96(24) 。

alt text

micropython 类的写法 这个不是很对

c
typedef struct {
    ...
} mp_obj_myfunc_read_t;

typedef struct {
    mp_obj_base_t base; // 必须的
    mp_obj_t stream;
    uint8_t format : 2;
    uint8_t window_bits : 4;
    bool close : 1;
    mp_obj_myfunc_read_t *read;
} mp_obj_myfunc_t;

static mp_obj_t myfunc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) {
    // args: stream, format=NONE, wbits=0, close=False
    mp_arg_check_num(n_args, n_kw, 1, 4, false);

    mp_int_t format = n_args > 1 ? mp_obj_get_int(args_in[1]) : DEFLATEIO_FORMAT_AUTO;
    mp_int_t wbits = n_args > 2 ? mp_obj_get_int(args_in[2]) : 0;

    // 检测输入格式
    if (format < DEFLATEIO_FORMAT_MIN || format > DEFLATEIO_FORMAT_MAX) {
        mp_raise_ValueError(MP_ERROR_TEXT("format"));
    }
    if (wbits != 0 && (wbits < 5 || wbits > 15)) {
        mp_raise_ValueError(MP_ERROR_TEXT("wbits"));
    }

    mp_obj_myfunc_t *self = mp_obj_malloc(mp_obj_myfunc_t, type); /**定义一个结构体对象,分配空间,并且赋值 */
    self->stream = args_in[0];
    self->format = format;
    self->window_bits = wbits;
    self->read = NULL;
    self->close = n_args > 3 ? mp_obj_is_true(args_in[3]) : false;

    return MP_OBJ_FROM_PTR(self); /** 返回mp obj */
}

micorpython核心功能

c
int pyexec_frozen_module(const char *name, bool allow_keyboard_interrupt)

idf_component_register(EMBED_FILES ...) 会被编译到app中

micropython的py目录下,定义了obj array print等基础的内容,extend文件夹下面定义了外设如spi i2c等的通用功能。 micropython的 gc 执行时间会随着使用内存的使用大小而增长,如果使用del或者clear标记不用内存,那么gc会非常快,约5ms。 在自动模式下,500ms左右自动gc一次。 alt text

micropython对象生成一次后不会额外占用内存,内存都是对象产生时分配、占用。

通过文件系统保存数据很慢,最好从底层实现。

mic 的正负极短路导致板子无法正常烧写,后面发现的时候已经晚了。有点尴尬,我还拆掉了两个模拟开关。

文件结构

  • boards 下面是板子配置
    • manifest.py 用来指定 freeze 的python文件
      • include("$(PORT_DIR)/boards/manifest.py") 包含默认
      • freeze("modules") 设置自定义
    • mpconfigboard.h 用来设置 MICROPY 全局参数,比如 板名 MICROPY_HW_BOARD_NAME
    • mpconfigboard.cmake 用来指定 参数配置
      • set(SDKCONFIG_DEFAULTS boards/sdkconfig.base ... )用于配置SDK
      • set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) 用于设置manifest.py
    • sdkconfig.board 配置sdk
    • pins.csv 设置引脚

Released under the MIT License.