1 Star 0 Fork 0

孙全 / MF1-User-Manual

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
MF1模块二次开发说明_old.md 16.26 KB
一键复制 编辑 原始数据 按行查看 历史
柯钿爽 提交于 2020-04-04 14:08 . Modify description

MF1模块二次开发说明

如果有任何的需求或者BUG,请发邮件至support@sipeed.com

SDK中只包含固件代码, 模型文件需要另外生成(出厂已烧录), 具体请邮件联系我们

本文档是旧的SDK说明, 请参考新的文档

目录

工程目录说明

本工程基于kendryte-standalone-sdk

!!!SDK下载连接!!!, 工具链下载链接

用户只需要关心src/Ai_Module_MF1_lib_test目录下的文件

.
├── board.c 板子外设的初始化等
├── board.h
├── build 编译目录
├── driver 板子外设驱动目录,包含lcd,flash,sd_card等
├── face_lib 人脸识别库,以及一些回调操作
├── lib 一些使用到的第三方库
├── main.c 主函数
├── network esp8285网络驱动
├── project.cmake
├── README.md
├── system_config.h 系统配置
├── uart_recv 串口协议接受处理
└── ui ui操作

工程编译

建议使用Ubuntu或其他Linux发行版进行编译, 本工程并未在Kendryte-IDE中验证过

src/Ai_Module_MF1_lib_test目录下打开终端, 执行

cd build
cmake ../../../ -DTOOLCHAIN=/opt/riscv-toolchain/bin && make

开始编译, 编译完成后, 在build目录下生成Ai_Module_MF1_lib_test.bin,使用工具烧录到模块中

下载固件

用户可以使用kflash_gui来下载程序

具体流程为:

  • ① 打开需要烧录的固件,

    如果是bin文件, 请确保地址为0x00,

    kfpkg文件时, 不需要选择地址

  • ② 选择开发板型号, MF1模块请选择Sipeed Maix Bit With Mic

  • ③ 选择串口, MF1模块, 请选择第一个串口

  • ④ 点击下载, 开始下载

升级ESP8285固件

现在(2019.08.14之前)esp8285出厂默认烧录的是AT固件, 在MF1中使用的是SPI与模块进行通信, 所以需要更新一下固件.

更新esp8285固件, 需要将使能引脚打开, 烧录预编译好的固件来使能wifi

①:短接这个触点到GND然后上电

②:使用这个串口进行esp82825的固件更新

esp8285 SPI固件下载地址

flash_download_tools下载地址

flash_download_tools下载选项

〇:注意选择ESP8285下载, 千万不要选择了ESP8266

①:选择之前下载的固件, 地址为0

②:选择晶振频率为40M

③:选择flash频率为40M

④:选择flash大小为8Mbit

⑤:选择对应的串口, 波特率建议选择为115200

⑥:点击开始下载

人脸识别库API说明

人脸识别API

uint8_t face_lib_init_module(void);

初始化人脸识别库,返回值为0的时候模块才可正常使用

uint8_t face_lib_regisiter_callback(face_lib_callback_t *cfg_cb);

注册人脸识别过程中一些事件回调函数,请参考例程中已经实现的函数

void face_lib_run(face_recognition_cfg_t *cfg);

进行人脸识别,需要摄像头是正常的,用户可以设置一些配置信息

串口协议库API

可以使用mqtt进行通信, 但是目前无法计算图片的特征值.

uint8_t protocol_send_init_done(void);

模块初始化完成

void protocol_prase(unsigned char *protocol_buf);

进行协议数据的解析,目前仅支持内置一些的指令,之后用户可添加自定义指令

void protocol_cal_pic_fea(uint8_t *jpeg_buf, uint32_t jpeg_len);

接收完图片之后进行图片特征值的计算

uint8_t protocol_send_cal_pic_result(uint8_t code, char *msg, float feature[FEATURE_DIMENSION], uint8_t *uid, float prob);

发送计算图片特征值结果

uint8_t protocol_send_face_info(face_obj_t *obj,
                                float score, uint8_t uid[UID_LEN], float feature[FEATURE_DIMENSION],
                                uint32_t total, uint32_t current, uint64_t *time);

识别到人脸之后,发送人脸信息,具体的使用方法请参考例程

extern volatile uint8_t face_lib_draw_flag;

lib中是否要调用来绘图标志

FLASH读写API

w25qxx_status_t w25qxx_init(uint8_t spi_index, uint8_t spi_ss, uint32_t rate);
w25qxx_status_t w25qxx_read_id(uint8_t *manuf_id, uint8_t *device_id);
w25qxx_status_t w25qxx_write_data(uint32_t addr, uint8_t *data_buf, uint32_t length);
w25qxx_status_t w25qxx_read_data(uint32_t addr, uint8_t *data_buf, uint32_t length);
w25qxx_status_t my_w25qxx_read_data(uint32_t addr, uint8_t *data_buf, uint32_t length, w25qxx_read_t mode);

对板载的16MByte FLASH的读写API

CAMERA操作API

int dvp_irq(void *ctx);

DVP中断回调,在Board.c中进行注册

int gc0328_init(void);

GC0328初始化,在Board.c中调用, 初始化摄像头

extern volatile uint8_t g_dvp_finish_flag

摄像头接收完一帧标志

Driver 目录说明

.
├── flash.c flash 读写
├── flash.h
├── font.c lcd显示字库
├── font.h
├── lcd_sipeed sipeedlcd驱动板驱动程序, 暂未调试好
├── lcd_ssd1963 ssd1963屏幕控制器驱动, 内存占用过大, 暂不支持
├── lcd_st7789 板载st7789屏幕控制器驱动, 默认使用
├── sd_card.c gpio模拟的sd_card驱动
└── sd_card.h

Flash API说明

void flash_init(void);

flash初始化

int flash_delete_face_info(uint32_t id);

删除保存在flash中, 指定id对应的人脸信息

int flash_delete_face_all(void);

删除flash中的所有人脸信息

int flash_save_face_info(uint8_t *image, float *features, uint8_t *uid, uint32_t valid, char *name, char *note, uint8_t *ret_uid);

保存人脸信息到flash中, featuresuid必需

int flash_get_saved_faceinfo(face_info_t *info, uint32_t index);

flash中读取指定index的信息

uint32_t flash_get_id_by_uid(uint8_t *uid);

使用uid获取对应的id

uint8_t flash_load_cfg(board_cfg_t *cfg);
uint8_t flash_save_cfg(board_cfg_t *cfg);
uint8_t flash_cfg_print(board_cfg_t *cfg);
uint8_t flash_cfg_set_default(board_cfg_t *cfg);

使用flash保存一些配置, 用户可添加自己的配置, 但不可删除已有的

Sd_card API说明

uint8_t SD_Initialize(void);
uint8_t SD_ReadDisk(uint8_t *buf, uint32_t sector, uint8_t cnt);
uint8_t SD_WriteDisk(uint8_t *buf, uint32_t sector, uint8_t cnt);

Sd_card初始化与读写, 用户不需要关心, 只需要使用文件系统进行操作即可

lib 目录说明

.
├── base64 base64编解码
├── cJSON cJOSN解析库
├── fmath.c 数学库函数实现
├── fmath.h
├── img_op.c 一些图片的操作
├── img_op.h
├── jpeg_compress jpeg图片压缩
├── jpeg_decode jpeg解码
├── oofatfs sd_card文件系统
├── sd_op.c sd_card文件系统封装的一些操作
└── sd_op.h

base64 API说明

unsigned char *base64_encode(const unsigned char *src, size_t len, size_t *out_len);
unsigned char *base64_decode(const unsigned char *src, size_t len, size_t *out_len);

base64编解码

cJSON API说明

cJSON是一个很成熟的库了, 具体的使用请百度或者谷歌.

jpeg_compress API说明

uint8_t reverse_u32pixel(uint32_t *addr, uint32_t length);

由于dvp输出的rgb565图像字节序有问题, 所以在进行jpeg编码之前, 需要将图像进行一次字节序调整

bool jpeg_compress(jpeg_encode_t *src, jpeg_encode_t *dst, int quality, bool realloc);

jpeg编码函数

Demo

    jpeg_encode_t jpeg_src, jpeg_out;
    //image_tmp,中间变量
    //display_image,dvp输出图像缓存
    memcpy(image_tmp, display_image, IMG_W * IMG_H * 2);
    reverse_u32pixel(image_tmp, 320 * 240 / 2);

    jpeg_src.w = 320;
    jpeg_src.h = 240;
    jpeg_src.bpp = 2;
    jpeg_src.data = image_tmp;

    jpeg_out.w = jpeg_src.w;
    jpeg_out.h = jpeg_src.h;
    jpeg_out.bpp = JPEG_BUF_LEN;
    jpeg_out.data = jpeg_buf;//jpeg编码输出缓存

    if(jpeg_compress(&jpeg_src, &jpeg_out, 80, 0) == 0)
    {
        printf("w:%d\th:%d\tbpp:%d\r\n", jpeg_out.w, jpeg_out.h, jpeg_out.bpp);
    } else
    {
        printf("jpeg encode failed\r\n");
        return;
    }

jpeg_decode API说明

用户只需要关心picojpeg_util.h中的函数

//out_img,解码输出缓存
//buf,jpeg图片缓存
//buf_len, jpeg图片缓存大小
//rgb565, 是否解码为rgb565, 为0时, 解码输出为rgb888
jpeg_decode_image_t *pico_jpeg_decode(uint8_t *out_img, uint8_t *buf, uint32_t buf_len, uint8_t rgb565);

解码jpeg图片,

oofatfs API说明

文件系统的操作, 请参考oofatfs文档

fmath API说明

用户基本不使用, 不用关心

img_op API说明

一些图片的基本操作

sd_op API说明

暂时未封装太多文件系统读写操作, 之后添加

ui 目录说明

保存了一些ui图片资源

uart_recv 目录说明

串口通信协议的一些操作, 主要是串口接受, 以及外设控制

network 目录说明

.
├── http http通信
│   ├── http_file.c http post和get文件
│   ├── http_file.h
│   ├── http_save_file.c http接受服务器返回
│   ├── http_save_file.h
│   ├── http_simple.c http普通操作
│   ├── http_simple.h
│   ├── mt_str.c
│   ├── my_str.h
│   ├── parsed_url.c 解析url
│   └── parsed_url.h
├── mqtt
│   ├── PubSubClient.c mqtt通信
│   └── PubSubClient.h
├── net_8285.c 封装的一些网络操作
├── net_8285.h
├── qrcode
│   ├── qrcode.c 二维码识别
│   └── qrcode.h
└── wifi
├── spi spi驱动
├── utility
├── WiFiSpi.c
├── WiFiSpiClient.c
├── WiFiSpiClient.h
├── WiFiSpi.h
├── WiFiSpiServer.c
├── WiFiSpiServer.h
├── WiFiSpiUdp.c
└── WiFiSpiUdp.h

http API说明

uint32_t http_get_file(char *url,
                       char *custom_headers,
                       char *resp_header,
                       uint32_t resp_header_len,
                       uint8_t *file,
                       uint32_t file_len);

uint32_t http_post_file(char *url,
                        char *custom_headers,
                        uint8_t *body,
                        uint8_t *boundary,
                        uint8_t *post_file,
                        uint32_t post_file_len,
                        char *resp_header,
                        uint32_t resp_header_len,
                        uint8_t *file,
                        uint32_t file_len);

使用http进行postget文件

Demo

    uint32_t get_recv_len = http_get_file(
        srv_url,//请求地址
        NULL,//自定义请求头
        http_header,//服务器返回的头
        sizeof(http_header),//长度
        http_body,//接受缓存
        sizeof(http_body));//长度
    uint32_t post_recv_len = http_post_file(
        http_upload_face,//请求地址
        send_hdr,//请求头
        NULL,//post的body内容
        NULL,//分割字符串, 可不用
        upload->jpeg_addr,//post的文件地址
        upload->jpeg_len,//post的文件长度
        http_header,//服务器返回的头
        sizeof(http_header),//长度
        http_body,//接受缓存
        sizeof(http_body));//长度
uint32_t http_save_file(uint8_t sock, char *resp_header, uint32_t resp_header_len, uint8_t *file, uint32_t file_len);

解析服务器返回的数据, 不用关心

其他文件用户不需关心

mqtt API说明

uint8_t PubSubClient_connect0(const char *id);
uint8_t PubSubClient_connect1(const char *id, const char *user, const char *pass);
uint8_t PubSubClient_connect2(const char *id, const char *willTopic, uint8_t willQos, uint8_t willRetain, const char *willMessage);
uint8_t PubSubClient_connect3(const char *id, const char *user, const char *pass, const char *willTopic, uint8_t willQos, uint8_t willRetain, const char *willMessage);

连接mqtt服务器, 用户选择自己需要的函数使用

uint8_t PubSubClient_loop(void);

主函数中调用, 发送心跳包, 以及接受数据

uint8_t PubSubClient_publish(const char *topic, const uint8_t *payload, unsigned int plength);

发布消息

uint8_t PubSubClient_subscribe(const char *topic, uint8_t qos);

订阅主题

uint8_t PubSubClient_unsubscribe(const char *topic);

取消订阅主题

uint8_t PubSubClient_connected(void);

判断是否连接到服务器, 若没有, 需要进行重连

qrcode API说明

uint8_t find_qrcodes(qrcode_result_t *out, qrcode_image_t *img);

识别二维码, 具体的使用方法请参考例程net_8285.c

wifi API说明

包含8285的驱动, 用户不用关心

net_8285.c API说明

qr_wifi_info_t *qrcode_get_wifi_cfg(void);

扫描二维码, 获取wifi配置信息, 二维码格式{"t":"84:0D:8E:6C:62:9C","w":"Sipeed_2.4G","p":"Sipeed123."}

t:模块的MAC地址, 在初始化中有打印

w:热点的名称

p:热点的密码

生成的二维码版本不能太高, 以及容错级别要为L,建议使用barcodegenerator来生成

uint8_t spi_8266_init_device(void);

初始化8285模块

uint8_t spi_8266_connect_ap(uint8_t wifi_ssid[32],
                            uint8_t wifi_passwd[32],
                            uint8_t timeout_n10s);

连接对应ssid

void mqtt_reconnect(void);

mqtt掉线重连

uint8_t spi_8266_mqtt_init(void);

初始化mqtt连接, 用户可修改连接的服务器以及topic

void spi_8266_mqtt_send(char *buf,size_t len);

通过mqtt发送数据

如果使用WIFI,需要修改system_config.h中的CONFIG_ENABLE_WIFI1

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/sunshengquan110/MF1-User-Manual.git
git@gitee.com:sunshengquan110/MF1-User-Manual.git
sunshengquan110
MF1-User-Manual
MF1-User-Manual
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891