LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

AMP相关:2 Linux Mailbox子系统(基于TM32MP1的IPCC)概览

Mailbox子系统是一种用于处理期间的通信机制,通过消息队列和中断驱动信号来处理多个处理器之间的通信。主要包括Controller和Client两部分。

Mailbox子系统包括如下几部分:

  • Mailbox子系统核心。
  • Mailbox控制器驱动,比如STM32MP157的IPCC驱动。
  • 使用Mailbox Controller驱动的Mailbox Client驱动,比如remoteproc作为Client通过Mailbox和M4通信。

Mailbox子系统大致工作流程是:

  • 注册Mailbox Controller驱动到Mailbox子系统。
  • Mailbox Client驱动申请通道。
  • Mailbox Client发送数据,Mailbox Controller驱动配置硬件发送消息。当数据发送完成时,Mailbox Controller通过回调函数通知上层数据发送完成。
  • Mailbox Controller接收到数据时,将底层接受到的数据回调给上层。
  • 不使用通道时,Mailbox Client释放通道。

1 Mailbox配置

 Mailbox Controller配置如下:

Device Drivers
  Mailbox Hardware Support
    Generic ARM smc mailbox
    Mailbox Test Client
    STM32 IPCC Mailbox

2 Mailbox文件

 Mailbox Controller相关文件如下:

drivers/mailbox/
├── arm-smc-mailbox.c ├── mailbox.c--Mailbox子系统核心,提供Controller的注册/去注册,Channel申请释放和消息发送。 ├── mailbox-test.c--通用Mailbox测试示例。 ├── stm32-ipcc.c--ST的Mailbox Controller IPCC驱动。

3 Mailbox子系统以及API

3.1 Mailbox Controller API和数据结构

struct mbox_chan_ops定义了如何操作Maibox通道的操作函数集:

struct mbox_chan_ops {
    int (*send_data)(struct mbox_chan *chan, void *data);--发送数据。
    int (*flush)(struct mbox_chan *chan, unsigned long timeout);
    int (*startup)(struct mbox_chan *chan);--启动通道。
    void (*shutdown)(struct mbox_chan *chan);--关闭通道。
    bool (*last_tx_done)(struct mbox_chan *chan);--检查发送完成。
    bool (*peek_data)(struct mbox_chan *chan);--检查通道是否有未读取数据。
};

struct mbox_controller表示Mailbox控制器:

struct mbox_controller {
    struct device *dev;--与Mailbox关联的设备结构体。
    const struct mbox_chan_ops *ops;--定义了如何与Mailbox通道交互的操作函数集。
    struct mbox_chan *chans;--Mailbox包含的所有通道。
    int num_chans;--Mailbox包含的通道数。
    bool txdone_irq;--为真,则控制器支持通过中断来通知发送完成。
    bool txdone_poll;--为真,则控制器支持轮询机制来查询发送完成。
    unsigned txpoll_period;--轮询周期,单位为毫秒。
    struct mbox_chan *(*of_xlate)(struct mbox_controller *mbox,
                      const struct of_phandle_args *sp);
    /* Internal to API */
    struct hrtimer poll_hrt;
    struct list_head node;
};

一个Mailbox可以有一个或多个Channel,struct mbox_chan表示一个Mailbox通道:

struct mbox_chan {
    struct mbox_controller *mbox;
    unsigned txdone_method;
    struct mbox_client *cl;
    struct completion tx_complete;
    void *active_req;
    unsigned msg_count, msg_free;
    void *msg_data[MBOX_TX_QUEUE_LEN];
    spinlock_t lock; /* Serialise access to the channel */
    void *con_priv;
};

Mailbox Controller的注册和去注册API如下:

int mbox_controller_register(struct mbox_controller *mbox); /* can sleep */
void mbox_controller_unregister(struct mbox_controller *mbox); /* can sleep */
int devm_mbox_controller_register(struct device *dev,
                  struct mbox_controller *mbox);
void devm_mbox_controller_unregister(struct device *dev,
                     struct mbox_controller *mbox);

从Channel接收消息API:

void mbox_chan_received_data(struct mbox_chan *chan, void *data); /* atomic */
void mbox_chan_txdone(struct mbox_chan *chan, int r); /* atomic */

3.2 Mailbox Client API和数据结构

struct mbox_client表示一个Mailbox客户端:

struct mbox_client {
    struct device *dev;--指向客户端设备的设备结构体。
    bool tx_block;--为真,客户端在发送消息时将阻塞,直到最后一条消息被传输完成。
    unsigned long tx_tout;--定义客户端超时前等待消息传输完成的最大时间,以毫秒为单位。
    bool knows_txdone;

    void (*rx_callback)(struct mbox_client *cl, void *mssg);--当Mailbox控制器接受到消息是,调用此函数来通知客户端。
    void (*tx_prepare)(struct mbox_client *cl, void *mssg);--发送消息前,调用此函数来准备消息。
    void (*tx_done)(struct mbox_client *cl, void *mssg, int r);--消息发送完成后,调用此函数来通知客户端发送操作的结构。
};

Mailbox Client获取释放Channel、发送消息等API:

struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
                          const char *name);
struct mbox_chan *mbox_request_channel(struct mbox_client *cl, int index);
int mbox_send_message(struct mbox_chan *chan, void *mssg);
int mbox_flush(struct mbox_chan *chan, unsigned long timeout);
void mbox_client_txdone(struct mbox_chan *chan, int r); /* atomic */
bool mbox_client_peek_data(struct mbox_chan *chan); /* atomic */
void mbox_free_channel(struct mbox_chan *chan); /* may sleep */

4 Mailbox硬件模块IPCC

 IPCCInter-Process Communication Controller处理器间通信控制器,,用于在两个 CPU之间进行信号交换

IPCC 硬件模块有 6 个双向通道, 每个通道分为两个子通道, 6 个双向通道则共有 12 个子通道。

5 STM32 Mailbox驱动

5.1 STM32 IPCC DTS

 IPCC DTS包括两个中断,分别是rx/tx:

        ipcc: mailbox@4c001000 {
            compatible = "st,stm32mp1-ipcc";
            #mbox-cells = <1>;
            reg = <0x4c001000 0x400>;
            st,proc-id = <0>;
            interrupts-extended =
                <&exti 61 1>,
                <&intc GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
            interrupt-names = "rx", "tx";
            clocks = <&rcc IPCC>;
            wakeup-source;
            power-domains = <&pd_core>;
            status = "disabled";
        };

5.2 STM32 IPCC驱动

 IPCC驱动作为Mailbox控制器驱动负责:

  • 获取中断号,并为tx/rx创建处理函数。
  • 配置唤醒功能。
  • 将IPCC作为Mailbox注册到Mailbox子系统。
stm32_ipcc_driver
  stm32_ipcc_probe
    platform_get_irq_byname--获取rx和tx中断。
    devm_request_threaded_irq--注册rx和tx中断。
      stm32_ipcc_rx_irq--A7 IPCC接收中断处理函数。
        mbox_chan_received_data--调用Mailbox Client的rx_callback函数进行处理,即stm32_rproc_mb_callback
      stm32_ipcc_tx_irq--A7 IPCC发送中断处理函数。
        mbox_chan_txdone
          tx_tick
            msg_submit--调用Mailbox Channel操作函数的send_data发送数据。
            --调用Malbox Client的tx_don函数。
    device_set_wakeup_capable
    dev_pm_set_wake_irq
    devm_mbox_controller_register--初始化mbox_controller后,将其注册到Mailbox Controller子系统。操作函数集为stm32_ipcc_ops。

stm32_ipcc_ops提供了对IPCC使能、关闭、发送数据的操作函数:

static const struct mbox_chan_ops stm32_ipcc_ops = {
    .send_data    = stm32_ipcc_send_data,
    .startup    = stm32_ipcc_startup,
    .shutdown    = stm32_ipcc_shutdown,
};

 

posted on 2024-07-07 23:59  ArnoldLu  阅读(280)  评论(0编辑  收藏  举报

导航