4.3.29.3. SSF中间件开发指南
基本概念
SSF= SGF(Smart Graph Framework)+ SMF(Smart Message Framework,其中SIPC)
代码adsp/ssf
SGF
代码adsp/ssf/sgf
SGF是
1、音频
2、音频
SGF包含
Module是dsp数据处理
定义adsp/ssf/sgf/ar/src/module.c
实现adsp/ssf/sgf/modules
Component包含
头文件adsp/ssf/sgf/ar/include/comp.h
Data Port是Component数据Input和Output。一个Component可以
头文件adsp/ssf/sgf/ar/include/comp.h


Connector是Connector Base和Connector RB两种,前者
头文件adsp/ssf/sgf/ar/include/conn.h
Graph是
头文件adsp/ssf/sgf/ar/include/graph_factory.h
代码adsp/ssf/sgf/conf/src/config_ar_x5.c
Trigger被Timer Interrupt,I2S Interrupt,DMA Interrupt。
也
Zone用来

整个Graph的
定义comp_param结构zone_id字
SMF

代码adsp/ssf/smf
整体
通讯
层 框架(SIPC):
封装 SIPC Instance实例
用来 表示 传输 实例,下面 可以 有 多个 传输 通道(Channel)。 一个
核 可以 有 多个 通讯 实例Instance。 封装SIPC Channel实例
用来 表示 传输 通讯 通道。
消息
分发 层 框架(dispatcher): 为services提供 服务,不 负责 解析msg的 内容,时序 上线 运行dispatcher运行services,services产生 相应 的 待处理 命令 后,dispatcher再 处理。
消息
分发Dispatcher维护 一个 消息 队列 和 一个 分发 线程。 接收SIPC消息,找到
对应 的services进行 解析。 接受 消息 的 时候 会 轮训services->category和msg->category通过category_id区分 是 哪个 服务 的 消息。 靠
常驻 线程 运行disp->msg_queue中 的 指令。
应用服务
层 框架(services)
每
一个 应用服务Service对接 其他 应用Application模块。 支持
定制 应用服务Service。 应用服务Service用来
接收 消息 分发 层Dispatcher发送 过来 的 消息。 应用服务Service可以
申请 多个 通讯 通道Channel。 应用服务Service支持 借助 通讯 通道Channel向 不同 的 核 发送 消息。 可以 注册 多个service,挂 在g_disp链上。
service解析
1.control信息:service负责
2.pipeline信息:直接
SIPC
SIPC(Super Inter-Processor Communication) 是 GUA 芯片IPC传输,这样

Sipc 分为
Sipc interface - 对外
提供 某 一个 板级 方案,用来 控制 创建 多少 个instance和channel 用来 进行 通讯,具体 实现 由sipc driver 实现。 Sipc driver - 用来
实现 sipc 接口,并 调用 sipc channel和 sipc intance 的 接口,创建instance和 所 需要 的channel。 Sipc transport - 用来
实现 sipc channel 和 sipc instance 的 接口,HB-IPC需要 实现 这 一层。
路由配置
路由/adsp/ssf/sgf/conf/src/config_ar_x5.c文件zone中例
Component配置描述
struct comp_param {
uint32_t cuid;
char name[16];
uint32_t zone_id;
uint32_t rate;
uint32_t channel;
uint32_t bitdepth;
uint32_t period;
ele_attr_t attr;
uint32_t muid;
trigger_source_t trigger;
data_port_cfg_t in_port;
data_port_cfg_t out_port;
};
1.uint32_t cuid;
Component Unique ID,使用
2.char name[16];
Component Name,注意
3.uint32_t zone_id;
表明
4.uint32_t rate;
Component能够
5.uint32_t channel;
Component能够
6.uint32_t bitdepth;
Component能够
7.uint32_t period;
Component每帧
8.ele_attr_t attr;
Component的
/**
* element attribute enum
* which shows element belong to downlink or uplink
* and shows whether has thread
*/
typedef enum {
ELE_ATTR_DL = BIT(0),
ELE_ATTR_UL = BIT(1),
ELE_ATTR_THREAD = BIT(2),
ELE_ATTR_IL = BIT(5), /* interleaved */
ELE_ATTR_NIL = BIT(6), /* noninterleaved */
} ele_attr_t;
9.uint32_t muid;
Module Unique ID,通过 GEN_MOD_UID 宏
10.trigger_source_t trigger;
表明
typedef enum trigger_source {
TRIGGER_I2S0_DMA_TX,
TRIGGER_I2S0_DMA_RX,
TRIGGER_I2S1_DMA_TX,
TRIGGER_I2S1_DMA_RX,
TRIGGER_APP_START,
TRIGGER_APP_WRITE = TRIGGER_APP_START,
TRIGGER_SOURCE_BUFFER, /* Use source block ringbuffer to trigger process*/
} trigger_source_t;
10.data_port_cfg_t in_port;
11.data_port_cfg_t out_port;
Component的
DEF_NONE_PORT // 没有端口
DEF_SINGLE_PORT(2) // 定义一个使用2个连续channel的端口
// 定义多个端口,每个端口使用 PORT(index, offset, cnt) 宏定义进行描述,连续的通道数
// PORT的第一个参数是port id,第二个是起始通道,第三个是通道数。
// (0,0,2)代表id为1的输出,会输出从0开始计数的两个通道(数组从0开始计数)。即第一、第二通道。
DEF_MULTI_PORTS(
PORT(0, 0, 2),
PORT(1, 2, 4)
)
// PORT_MASK定义离散的通道数,如71 = 1000111 代表输出1237四个通道
DEF_MULTI_PORTS(
PORT_MASK(0, 0, 71),
PORT_MASK(1, 0, 71),
PORT_MASK(2, 0, 71)
)
Link关系描述
一个link描述
struct link_param {
uint32_t source_id;
uint32_t sink_id;
struct {
conn_attr_t conn_attr;
uint32_t default_status;
uint16_t sink_port_id;
uint16_t source_port_id;
} conn_param;
};
其中,component cuid为
具体示例
以
static link_param_t capture_links[] = {
{
.source_id = CUID_I2S_RX,
.sink_id = CUID_CAPTURE_DEVICE_SPLITTER,
.conn_param = {
.conn_attr = CONN_ATTR_BASE,
.default_status = CONN_STATUS_LINKED | CONN_STATUS_SWITCH_ON,
.source_port_id = PORT_ID(0),
.sink_port_id = PORT_ID(0),
},
},
{
.source_id = CUID_CAPTURE_DEVICE_SPLITTER,
.sink_id = CUID_FE_NORMAL_RECORD,
.conn_param = {
.conn_attr = CONN_ATTR_RB,
.default_status = CONN_STATUS_LINKED,
.source_port_id = PORT_ID(1), // 从源的port1输入
.sink_port_id = PORT_ID(0), // 送入
},
},
};
涉及Component如下
{
.cuid = CUID_I2S_RX,
.name = "i2s-rx",
.zone_id = 1,
.rate = 16000,
.channel = 8, // 1100 1111 从低到高,四路mic 2路ref,当前音频板为8通道
.bitdepth = PLATFORM_BIT_DEPTH,
.period = 256,
.attr = ELE_ATTR_UL | ELE_ATTR_IL | ELE_ATTR_THREAD,
.muid = MUID_I2S_RX,
.trigger = TRIGGER_I2S1_DMA_RX,
.in_port = DEF_NONE_PORT,
.out_port = DEF_SINGLE_PORT(8),
},
{
.cuid = CUID_CAPTURE_DEVICE_SPLITTER,
.name = "cp_splitter",
.zone_id = 1,
.rate = 16000,
.channel = 8,
.bitdepth = PLATFORM_BIT_DEPTH,
.period = 256,
.attr = ELE_ATTR_UL | ELE_ATTR_NIL,
.muid = MUID_SPLITTER_2,
.trigger = TRIGGER_SOURCE_BUFFER,
.in_port = DEF_SINGLE_PORT(8),
.out_port = DEF_MULTI_PORTS(
PORT_MASK(0, 0, 71), // 0100 0111 3mic + 1ref port0
PORT_MASK(1, 0, 79), // 0100 1111 4mic + 1ref port1
PORT_MASK(2, 0, 71) // 暂无使用
),
},
{
.cuid = CUID_FE_NORMAL_RECORD,
.name = "Normal_Record",
.zone_id = 1,
.rate = 16000,
.channel = 5, // 5路音频
.bitdepth = PLATFORM_BIT_DEPTH,
.period = 256,
.attr = ELE_ATTR_UL | ELE_ATTR_IL,
.muid = MUID_FE_UL_1,
.trigger = TRIGGER_I2S1_DMA_RX,
.in_port = DEF_SINGLE_PORT(5), // 5路音频
.out_port = DEF_NONE_PORT,
}
算法移植指南
中间件
编写module
在SGF框架
static struct module_desc mod_hisf_lp = {
.mtid = MTID_HISF_LP,
.name = "HISF_LP",
.ops = {
.cmd = hisf_cmd,
.process = hisf_process,
.stack_size = hisf_get_stackreq,
.create = hisf_create,
},
};
common_module_register(mod_hisf_lp);
主要
module放在 adsp\ssf\sgf\plugin\src目录adsp\ssf\algo目录
定义MTID (Module Type ID)
MTID是adsp\ssf\sgf\conf\include\config_common.h内,也
#define MTID_HISF_LP (0x45)
#define MTID_HISF_NORMAL (0x46)
将
添加文件到Makefile
将module以及
MOD_LIB_SRC += mod_hisf_lp.c
定义CUID/MUID
算法adsp\ssf\sgf\conf\include\config_ar_x5.h 中
#define CUID_HISF_LP GEN_COMP_UID(CTID_BASE, MTID_HISF_LP, 0x1)
#define CUID_HISF_NORMAL GEN_COMP_UID(CTID_BASE, MTID_HISF_NORMAL, 0x1)
#define MUID_HISF_LP GEN_MOD_UID(MTID_HISF_LP, 0x1)
#define MUID_HISF_NORMAL GEN_MOD_UID(MTID_HISF_NORMAL, 0x1)
配置Graph
见路由
A核与DSP数据通信
四路alsa pcm device介绍:
device0:SMF FE raw —— mic原始
音频,包含 回采。 device1:SMF FE ASR —— 一级
唤醒 后 的ASR音频,连续 的,有1秒 的buffer。 device2:SMF FE history ——一级
唤醒,4秒 的 唤醒 词 音频,有 四秒 的 缓冲。 device4:SMF FE hisf normal —— 正常
功耗 预处理 后 音频,包含 送 唤醒sdk的enhanced音频 和 送vad sdk的asr音频。
调试指南
Log
基本log打印,log level可adsp/ssf/sysdeps/xos/include/sys_log_cfg.h设置。
修改SYS_LOG_OUTPUT_LVL即可。
#define SYS_LOG_LVL_ASSERT 0
#define SYS_LOG_LVL_ERROR 1
#define SYS_LOG_LVL_WARN 2
#define SYS_LOG_LVL_INFO 3
#define SYS_LOG_LVL_DEBUG 4
#define SYS_LOG_LVL_VERBOSE 5
#define SYS_LOG_LVL_TOTAL_NUM 6
Backtrace
xt-addr2line 工具。
xt-addr2line 是
在adsp目录source env_hf5.sh后
例如

可以
xt-addr2line -e output/adsp -fpiC [地址]
以