当前位置: 首页 > news >正文

【STM32MP157 异核通信框架学习篇】(10)Linux下Remoteproc相关API (下)

文章目录

  • 1 概要
  • 2 Linux下Remoteproc相关API
    • 2.8 rproc 设备树节点
  • 3 总结

1 概要

使用正点原子的stm32mp157mini进行RPMSG多核通信试验。
硬件:STM32MP157
软件:STM32CubeIDE / STM32CubeMX

远程处理器(Remoteproc)框架负责根据固件资源表中可用的信息激活 Linux 端的进程间通信(IPC),本节我们来分析 Linux 下的 Remoteproc 相关驱动,了解 Remoteproc 是怎样控制远程处理器的。本小节的内容会涉及到分析代码,会比较枯燥乏味,如果只想了解 Remotepro使用方法,可以直接看本章的最后一小节。

本章分为如下几部分(文章末尾会附上链接):

  1. 资源表
  2. 存储和系统资源分配
  3. Linux 下 Remoteproc 相关 API
  4. 链接脚本
  5. Remoteproc 的使用

2 Linux下Remoteproc相关API

2.8 rproc 设备树节点

打开stm32mp151.dtsi 设备树文件,找到设备树中和M4相关的Remoteproc配置,如下:
在这里插入图片描述
在这里插入图片描述
在上面的代码段里,有三个节点:mlahb节点、m4_rproc节点和m4_system_resources节点。m4_rproc节点下就是加载和管理M4固件的配置信息。m4_system_resources节点(也就是M4的资源管理器)下就是M4的资源分配配置信息。第10行,compatible属性值为“st,stm32mp1m4”,在Linux内核源码中搜索此属性值找到对应的驱动文件为drivers/remoteproc/stm32_rproc.c,打开此文件找到如下内容:

1   static const struct of_device_id stm32_rproc_match[] = { 
2           { .compatible = "st,stm32mp1-m4" }, 
3           {}, 
4   }; 
5   MODULE_DEVICE_TABLE(of, stm32_rproc_match); 
6   /* 此处省略部分代码 */ 
7   static SIMPLE_DEV_PM_OPS(stm32_rproc_pm_ops, 
8                            stm32_rproc_suspend, stm32_rproc_resume); 
9  
10  static struct platform_driver stm32_rproc_driver = { 
11          .probe = stm32_rproc_probe, 
12          .remove = stm32_rproc_remove, 
13          .shutdown = stm32_rproc_shutdown, 
14          .driver = { 
15                  .name = "stm32-rproc", 
16                  .pm = &stm32_rproc_pm_ops, 
17                  .of_match_table = of_match_ptr(stm32_rproc_match), 
18          }, 
19  }; 
20  /* 向Linux内核注册stm32_rproc_driver驱动 */ 
21  module_platform_driver(stm32_rproc_driver); 
22  MODULE_DESCRIPTION("STM32 Remote Processor Control Driver"); 
23  MODULE_AUTHOR("Ludovic Barre <ludovic.barre@st.com>"); 
24  MODULE_AUTHOR("Fabien Dessenne <fabien.dessenne@st.com>"); 
25  MODULE_LICENSE("GPL v2"); 

上面的驱动代码是一个标准的platform驱动,第2行就是设备树下匹配到驱动程序的地方,在stm32_rproc_match中。第15行,成员name属性是stm32-rproc,即定义了驱动的名字是stm32-rproc,它是用于驱动与设备匹配的。

第17行,用于匹配对应的device,即匹配设备树中的节点。第21行module_platform_driver()函数向Linux内核注册stm32_rproc_driver这个platform驱动。当设备和驱动匹配成功以后,stm32_rproc_driver->probe函数(即stm32_rproc_probe()函数)就会被执行。下面,我们直接去
看stm32_rproc_probe()函数做了哪些操作。stm32_rproc_probe()函数在Linux内核源码的drivers/remoteproc/stm32_rproc.c文件下,其函数定义如下所示:

1   static int stm32_rproc_probe(struct platform_device *pdev) 
2   { 
3     struct device *dev = &pdev->dev; 
4     struct stm32_rproc *ddata; 
5     struct device_node *np = dev->of_node; 
6     struct rproc *rproc; 
7     int ret; 
8  
9     ret = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); 
10    if (ret) 
11            return ret; 
12 
13    rproc=rproc_alloc(dev,np->name,&st_rproc_ops,NULL,sizeof(*ddata)); 
14    if (!rproc) 
15            return -ENOMEM; 
16 
17    rproc->has_iommu = false; 
18    ddata = rproc->priv; 
19    ddata->workqueue = create_workqueue(dev_name(dev)); 
20    if (!ddata->workqueue) { 
21            dev_err(dev, "cannot create workqueue\n"); 
22            ret = -ENOMEM; 
23            goto free_rproc; 
24    } 
25 
26    platform_set_drvdata(pdev, rproc); 
27 
28    ret = stm32_rproc_parse_dt(pdev);
29    if (ret) 
30            goto free_wkq; 
31  if (!rproc->early_boot) { 
32            ret = stm32_rproc_stop(rproc); 
33            if (ret) 
34                    goto free_wkq; 
35    } 
36 
37    ret = stm32_rproc_request_mbox(rproc); 
38    if (ret) 
39            goto free_wkq; 
40 
41    ret = rproc_add(rproc); 
42    if (ret) 
43            goto free_mb; 
44 
45    return 0; 
46 
47  free_mb: 
48    stm32_rproc_free_mbox(rproc); 
49  free_wkq: 
50    destroy_workqueue(ddata->workqueue); 
51  free_rproc: 
52    if (device_may_wakeup(dev)) { 
53            dev_pm_clear_wake_irq(dev); 
54            device_init_wakeup(dev, false); 
55    } 
56    rproc_free(rproc); 
57    return ret; 
58  } 

第4行,ddata指针是ST官方的私有数据stm32_rproc结构体。

第6行,声明了一个rproc类型的结构体。

第9行,DMA相关配置。

第13行,rproc_alloc函数主要作用是分配一个新的rproc结构体空间,同时st_rproc_ops地址赋值给rproc->ops参数,目的是调用回调函数完成对应的功能(类似XXX_ops的结构体中的成员变量就是一些回调函数),这行的目的就是分配一个新的远程处理器(rproc)结构体,使用此函数创建 rproc 结构体后,应调用 rproc_add() 以完成远程处理器的注册,在后面我们会看到调用此函数。

第18行,保存ST官方的私有数据到rproc结构体里。

第19行,创建工作队列,workqueue的名称是设备的名字,每个workqueue就是一个内核进程,为系统创建一个内核线程。

第28行,调用stm32_rproc_parse_dt()函数来获取设备树中的属性,目的就是完成M4设备的配置。

第31~35 行,如果没有加载固件则调用stm32_rproc_stop 函数,该函数会做一些操作,如请求关闭远程处理器,此时传输阻塞,会打印“warning: remote FW shutdown without ack”,并将远程处理器状态设置为离线状态等。

第37行,stm32_rproc_request_mbox()函数为远程处理器申请邮箱,A7 和 M4 可通过邮箱发布数据。

第41行,rproc_add()函数在前面的介绍中我们已经了解了,就是注册一个远程处理器。

第56行,rproc_free()函数释放由 rproc_alloc ()分配的 rproc 。 下面我们来看看st_rproc_ops结构体,在stm32_rproc.c找到如下代码:
在这里插入图片描述
st_rproc_ops 结构体中有几个处理程序,每个处理程序对应一个回调函数,如 start 处理程序接受一个 rproc 结构体,然后打开设备电源并启动它。stop处理程序采用 rproc 并关闭远程处理器。kick处理程序接受一个 rproc 和一个放置新消息的虚拟队列的索引,调用此函数时会中断远程处理器并让它知道它有待处理的消息。find_loaded_rsc_table就是查找已经加载的固件资源表,执行的是stm32_rproc_elf_find_loaded_rsc_table()函数。 每个 Remoteproc 的实现至少应该提供 start 和 stop 处理程序,关于这些函数我们不必深入分析,只要我们知道这是ST官方实现操作M4相关的接口函数就行了。

3 总结

本章节讲述了Linux下Remoteproc相关API。

http://www.dtcms.com/a/614689.html

相关文章:

  • 企业建站服务退役军人215专业品牌网站建设
  • 杭州模板网站建站做国外夏令营的网站
  • 基于SpringBoot的房屋租赁管理系统【协同过滤推荐算法+可视化统计+合同签署】
  • 【MySQL | 基础】函数
  • Java Set
  • (60页PPT)数据治理与数据安全防护方案(附下载方式)
  • DSAC-T算法实现控制倒立摆
  • 学校网站建设需要多少钱wordpress添加首页导航
  • 开发区网站制作公司wordpress+系统安装
  • 什么是性能测试?它的分类?(负载测试、压力测试、并发测试等)
  • 4.3 Go 协程:goroutine
  • 查询缓存8.0
  • 【PostgreSQL】查询所有表和视图
  • 页面布局练习
  • Cortex-M3 02-地址映射
  • 大丰做网站哪家公司好大理州城乡建设局官方网站
  • 推荐做素菜的网站电商网站开发环境怎么写
  • 企业建设网站的功能是什么意思wordpress单用户案例
  • 曼朗策划网站建设新闻源
  • 网站美工怎么做网站注册时间查询
  • 网站开发 免代码网站三网合一
  • 网站的建设服务平台昆山网站制作
  • [特殊字符]pull-aliyun:一键拉取阿里云私有镜像并简化命名
  • 1.2 学习和使用汇编语言的目的
  • 电子商务网站建设需要的语言沐风wordpress
  • SpringMVC请求参数的绑定
  • C++03 标准详解:C++98的技术修订版
  • 网站做下载wordgoogle网站推广
  • 网站虚拟机可以自己做吗查询百度关键词排名
  • Java 实战:去重与排序(HashSet+TreeSet 应用)