API GUIDE / JPEGE / Middleware

G32S10 JPEGE Middleware 接口

Middleware 层接口:状态字段是 volatile,因为中断上下文会读取它。

1. 公开数据类型

1.1 im_jpege_state_t

状态含义
IM_JPEGE_STATE_UNINITIALIZED没有活动 MID 会话
IM_JPEGE_STATE_INITIALIZEDHAL/IRQ 已初始化,sequence 尚未配置
IM_JPEGE_STATE_CONFIGUREDsequence 已配置,可以启动下一帧
IM_JPEGE_STATE_RUNNING一帧已 arm,等待 frame-end 或异常事件
IM_JPEGE_STATE_ERROR帧异常结束,寄存器块等待复位和重新配置

状态字段是 volatile,因为中断上下文会读取它。im_jpege_get_state() 本身 不加锁,返回的只是读取瞬间的快照。

2. JPEGE MID 会话状态机

STATE  UNINITIALIZED
→
STATE  INITIALIZED
→
STATE  CONFIGURED
→
STATE  RUNNING
→
STATE  ERROR

UNINITIALIZED → INITIALIZED · im_jpege_init()

INITIALIZED / CONFIGURED → CONFIGURED · set_configure / encode

CONFIGURED → RUNNING · start_frame / encode

RUNNING → CONFIGURED · frame done + get_result

RUNNING → ERROR · timeout / overflow / frame-start abnormal

ERROR → INITIALIZED · reset / next encode

INITIALIZED / CONFIGURED / ERROR → UNINITIALIZED · deinit

状态转换表:

当前状态API结果
UNINITIALIZEDim_jpege_init()INITIALIZED
INITIALIZED / CONFIGUREDim_jpege_set_configure()CONFIGURED
CONFIGUREDim_jpege_start_frame()RUNNING;HAL 启动失败则回 CONFIGURED
RUNNINGim_jpege_wait_frame() 成功CONFIGURED
RUNNINGim_jpege_wait_frame() 异常ERROR
ERRORim_jpege_reset()INITIALIZED
ERRORim_jpege_encode()自动 reset 后重新配置
任意非 UNINITIALIZEDim_jpege_deinit()UNINITIALIZED

im_jpege_set_configure()、im_jpege_start_frame() 和im_jpege_wait_frame() 在 ERROR 状态都返回 IM_ERR_NOT_READY。需要先im_jpege_reset(),或者直接使用会自动恢复的 im_jpege_encode()。

3. API 详细说明

3.1 im_jpege_init()

error_code_t im_jpege_init(uint32_t timeout_ms);
  1. 检查会话必须为 UNINITIALIZED。
  2. 申请并使能 IRQ_JPEG_ENC。
  3. 调用 hal_jpege_init()。HAL 要求系统 systick 已初始化,否则返回 IM_ERR_NOT_READY。
  4. 注册 MID frame-event callback。
  5. 保存 frame-end 等待超时并进入 INITIALIZED。

timeout_ms == 0 时使用 IM_JPEGE_DEFAULT_TIMEOUT_MS,当前为 1000 ms。

返回:

返回值 原因
IM_OK 会话建立成功
IM_ERR_BUSY 会话已经存在
其他错误 IRQ 申请/使能或 HAL 初始化失败

初始化中 IRQ 已申请但 HAL 初始化失败时,IRQ 会被关闭。

3.2 im_jpege_start_frame()

error_code_t im_jpege_start_frame(const hal_jpege_frame_t *frame);

使用最近一次成功配置的 sequence arm 一帧,不等待 frame-end。

状态 行为
UNINITIALIZED IM_ERR_NOT_READY
INITIALIZED IM_ERR_NOT_READY,必须先配置
CONFIGURED 启动成功进入 RUNNING
RUNNING IM_ERR_BUSY
ERROR IM_ERR_NOT_READY

如果 hal_jpege_start_frame() 失败,MID 回到 CONFIGURED,已配置的 sequence 保留。

3.3 im_jpege_wait_frame()

error_code_t im_jpege_wait_frame(hal_jpege_frame_t *frame);

等待 start_frame() 已 arm 的帧完成。

  • 状态不是 RUNNING 时返回 IM_ERR_NOT_READY。
  • 等待到正常 FRAME_DONE 后,MID 先进入 CONFIGURED,再调用 hal_jpege_get_result() 同步输出 cache 并填写 frame->output_size。
  • 等待超时、overflow 或 frame-start abnormal 时进入 ERROR。

IRQ 事件到错误码的映射:

HAL 事件 MID 错误
HAL_JPEGE_IRQ_EVENT_FRAME_DONE IM_OK
HAL_JPEGE_IRQ_EVENT_TIMEOUT IM_ERR_TIMEOUT
HAL_JPEGE_IRQ_EVENT_OVERFLOW IM_ERR_HARDWARE
HAL_JPEGE_IRQ_EVENT_FRAME_START_ABNORMAL IM_ERR_HARDWARE

其中 HAL_JPEGE_IRQ_EVENT_OVERFLOW 是硬件定义的 PSRAM 区域覆盖异常:ISP 写入区域覆盖了 JPEG 正在读取的区域。它不表示 JPEG bitstream 输出 buffer 容量不足;输出 buffer 不足由 IM_ERR_NO_SPACE 表示。 | 未知事件 | IM_ERR_IO |

如果 frame-end 正常但 hal_jpege_get_result() 失败,例如输出容量不足返回 IM_ERR_NO_SPACE,MID 此时已经进入 CONFIGURED,不会因此进入 ERROR。

3.4 im_jpege_encode()

error_code_t im_jpege_encode(const im_jpege_job_t *job,
                             im_jpege_frame_t *frame);

同步编码一帧:

  1. 检查 job 和 frame 非空。
  2. UNINITIALIZED 返回 IM_ERR_NOT_READY。
  3. ERROR 状态先执行内部复位,若失败则返回复位错误。
  4. RUNNING 返回 IM_ERR_BUSY。
  5. 首次调用或 job 与已保存配置不同时,配置 sequence。
  6. 应用 frame->shadow。
  7. arm 当前帧。
  8. 等待 frame-end 并取结果。

编码成功后,frame->hal_frame.output_size 包含 JPEG 字节数。

配置复用比较字段:

  • param.width / height
  • param.pix_format
  • param.bayer_format
  • param.qp
  • param.qk_table
  • config.codec.restart_markers_en / restart_mcu_num
  • config.codec.qt_mode / qt_table
  • config.start_auto / reset_auto
  • config.wrap
  • config.ar_outstanding / awlen
  • config.isp_en
  • config.reset_cycle
  • config.hw_timeout.is_enabled / thrd

buffer 地址、buffer 容量和 frame.shadow 不参与配置比较。因此连续帧可以 复用 sequence,只更换地址或调整本帧 shadow。

3.5 im_jpege_set_configure()

error_code_t im_jpege_set_configure(const im_jpege_job_t *job);

显式配置 sequence。要求:

  • job != NULL

  • 状态不是 UNINITIALIZED

  • 状态不是 RUNNING

  • 状态不是 ERROR

成功后 MID 保存 job 副本并进入 CONFIGURED。该配置一直有效,直到被新的set_configure() / encode() 配置替换,或会话进入 ERROR、reset、deinit。

在 ERROR 状态下该接口返回 IM_ERR_NOT_READY,不会自动复位;自动恢复由im_jpege_encode() 完成。

3.6 im_jpege_reset()

error_code_t im_jpege_reset(void);

在任务上下文执行 HAL 寄存器块复位。

状态行为
UNINITIALIZEDIM_ERR_NOT_READY
RUNNINGIM_ERR_BUSY
INITIALIZED / CONFIGURED / ERROR执行 HAL reset

成功后进入 INITIALIZED,sequence 配置被清空,必须重新配置。复位失败时 状态保持或回到 ERROR。

3.7 im_jpege_get_state()

im_jpege_state_t im_jpege_get_state(void);

无锁返回当前状态快照。需要读取 callable 状态时,应以CONFIGURED 为准;RUNNING 表示还有一帧未完成。

3.8 im_jpege_deinit()

error_code_t im_jpege_deinit(void);

释放 HAL、IRQ、waiter 和 callback 资源,进入 UNINITIALIZED。当前实现无论 是否有活动会话都返回 IM_OK;没有会话时是空操作。