在上一篇文章中,我们搭建了一个AMP的环境,而且在CPU0和CPU1上分别跑了两个没有交集的线程。这篇文章中我们需要让两个CPU之间能够进行通信。而传递数据采用了共享内存,我们将共享内存设置在OCM(On Chip Memory)内。


在我们的设计中CPU0负责进行显示控制7段数码管和LED灯,显示的数据从OCM中定义的显示缓冲区读取,采用定时器中断进行刷新扫描显示;CPU1负责进行键盘扫描,通过GPIO中断扫描4位独立按键和4×4矩阵键盘的键值,将对应键值的显示码按照循环的方式写入OCM中的显示缓冲区。

#define DISPLAY_BUF             ((volatile unsigned char *)(0xFFFF0000U))
//显示缓冲区按字节访问限定为8字节

我将显示缓冲区的8个字节定义在了OCM的最后一块儿中。


在没有做其他设置的情况下ZYNQ上电后地址空间分别如上图所示。OCM共256KB按照64KB分为4块,其中前三块在SDK中表述为RAM0占192KB处于地址空间的最开头和DDR共用地址空间,最后一块64KB处于地址空间的最后。ZYNQ的DDR固定占地址空间的最开头1GB字节因而ZYNQ的DDR最大容量就只有1GB。为了避开OCM从上图可知实际使用的DDR只有1023MB(最开头的1MB被保留避开OCM的前三块)。从0x40000000到0xDFFFFFFF的2GB空间留给了自定义IP或者其他IP的寄存器,从BSP的xparameters.h可以看出在PL部分添加的IP其基址都是从0x40000000开始的,而ZYNQ自己的寄存器则从0xE0000000开始编制,具体寄存器内容请查阅UG585的附录B Register Details。其实Standalone作为基础的BSP所作的工作都是在通过指针访问各个寄存器而已,在不考虑安全性的前提下可以完全不用BSP直接操作寄存器对ZYNQ进行操作。

下面是程序运行后的几张效果图:





由于工程比较大,这里就只把和OCM相关的代码贴出来和大家分享了。

在CPU0和CPU1的C源文件中均在相同的地址定义OCM的8字节为显示缓冲区:

#define DISPLAY_BUF             ((volatile unsigned char *)(0xFFFF0000U))
//显示缓冲区按字节访问限定为8字节该定义应在两个CPU的源文件中均定义

CPU0中唤醒CPU1的地址定义

#define CPU1STARTADR            0x20000000U//CPU1的DDR起始地址从512MB字节开始
#define CPU1_START_UP_REG       0xFFFFFFF0U//用来存储上面地址的指针地址

CPU0中禁止OCM的Cache属性和唤醒CPU1的代码

    //Disable cache on OCM
    Xil_SetTlbAttributes(0xFFFF0000,0x14de2);  // S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0
    print("CPU0: writing startaddress for cpu1\n\r");Xil_Out32(CPU1_START_UP_REG, CPU1STARTADR);//该函数需包含xil_io.h
    //CPU1STARTADR=0xFFFFFFF0, CPU1STARTADR=0x20000000);
    dmb(); //waits until write has finished
    print("CPU0: sending the SEV to wake up CPU1\n\r");sev();dmb(); //waits until write has finished

CPU1中禁止OCM的Cache属性

    //Disable cache on OCM
    Xil_SetTlbAttributes(0xFFFF0000,0x14de2);           // S=b1 TEX=b100 AP=b11, Domain=b1111, C=b0, B=b0

CPU1扫描到按键后填充显示缓冲区的代码

   TimerExpired=(TimerExpired+1)%BUF_SIZE;//循环移动显示缓冲区的写入指针
   DISPLAY_BUF[TimerExpired]=Display_Code[KEY_Value-1];//在指针位置写入键值
   DISPLAY_BUF[BUF_SIZE]=TimerExpired;//记录新按键键值的指针位置
   xil_printf("CPU1: New key has been pushed ,update the display buffer.\r\n");

CPU0在定时器中断中读取显示缓冲刷新显示的代码

   XScuTimer_ClearInterruptStatus(TimerInstancePtr);//清除定时器中断标志
   TimerExpired=(TimerExpired+1)%4;//循环移动显示缓冲区读取指针
   XGpio_DiscreteWrite(&Gpio_LEDS, SEG_CHANNEL, emerge_ledbus(DISPLAY_BUF[TimerExpired],DISPLAY_BUF[TimerExpired+4],Selected_Code[TimerExpired]));//将对应缓冲区内容送到7段数码管上
   XGpio_DiscreteWrite(&Gpio_LEDS, LED_CHANNEL, DISPLAY_BUF[DISPLAY_BUF[BUF_SIZE]]);//将最新一个按键的键值送到LED灯上

接下来是验证视频

如有问题欢迎评论留言或关注码峰社嵌入式群541931432进行讨论。

ZYNQ有两个CPU?(二)——OCM共享内存相关推荐

  1. ZYNQ有两个CPU?(三)——SGI异步通信

    ZYNQ有两个CPU?(三)--SGI异步通信 罗宾老师 嵌入式教师.码峰社QQ群541931432 19 人 赞同了该文章 前面两篇文章中我分享了ZYNQ上在Standalone环境下搭建AMP和用 ...

  2. ZYNQ有两个CPU?(一)——AMP搭建

    ** ZYNQ有两个CPU?(一)--AMP搭建 ** 本文转载自:https://zhuanlan.zhihu.com/p/30336605 当初Xilinx技术支持忽悠我用ZYNQ的时候这双核就是 ...

  3. 进程间通信(二)(共享内存)

    共享内存 通信原理: 开辟一块内存空间,各个进程将同一块物理内存空间映射到自己的虚拟地址空间中,通过虚拟地址进行访问,进而实现数据共享 特性:共享内存是最快的进程间通信方式,直接通过虚拟地址访问物理内 ...

  4. 【Linux篇】第十二篇——进程间通信(管道+system V共享内存)

    进程间通信介绍 概念 目的 本质 分类 管道 什么是管道 匿名管道 匿名管道的原理 pipe函数 匿名管道使用步骤 管道读写规则 管道的特点 管道的大小 命名管道 命名管道的原理 使用命令创建命名管道 ...

  5. PostgreSQL共享内存创建相关分析

    一.问题背景 最近一个生产库内存告警单个进程内存使用超过25%,发现是一个远程容灾postgres库.告警抓到的进程是wal receiver进程,使用了近85GB内存.top查看后,发现是SHR使用 ...

  6. 【GPU结构与CUDA系列4】GPU存储资源:寄存器,本地内存,共享内存,缓存,显存等存储器细节

    0 软件抽象和硬件结构对应关系的例子 把GPU跟一个学校对应起来,学校里有教学楼.操场.食堂,还有老师和学生们:很快有领导(CPU)来检查卫生(需要执行的任务Host程序),因此这个学校的学生们要完成 ...

  7. Linux系统中消息队列,共享内存、信号和线程的基本操作使用方法

    Linux系统中消息队列,共享内存.信号和线程高级操作 第十一章 消息队列 10.1消息队列定义 10.2 消息队列特点 10.3 key值 10.4 创建消息队列 10.4.1 发送消息 10.4. ...

  8. system v和posix的共享内存对比 共享内存位置

    参考 http://www.startos.com/linux/tips/2011012822078.html 1)Linux和所有的UNIX操作系统都允许通过共享内存在应用程序之间共享存储空间. 2 ...

  9. Linux进程间通信——使用共享内存

    下面将讲解进程间通信的另一种方式,使用共享内存. 一.什么是共享内存 顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存.共享内存是在两个正在运行的进程之间共享和传递数据的一种非常有效的方式 ...

最新文章

  1. 医疗卫生信息化 医学信息 医疗信息化 医院管理 资料下载
  2. html可以有多个main吗,main和div
  3. linux编辑文档windows,1.9vim编辑器linux内核的底层文本编辑器,跟windows系统上的文本文档类似,大部分用这个工具进行文本的编辑,这个工具的操作方式基本上用不到鼠标,多是...
  4. php ssc 源码_吃透这篇,你也能搭建出一个高并发和高性能的系统
  5. 学堂在线计算机挂了咋办,各位师兄师姐我想问下计算机挂了是直接重修吗(#泪)...
  6. delphi7存取配置文件与sqlserver数据库连接_Delphi7存取配置文件与SQLServer数据库连接...
  7. 程序员面试金典 - 面试题 01.09. 字符串轮转
  8. Mounting A Windows Share On AIX Using CIFS
  9. 我和一位快递小哥的故事
  10. 跟着王道考研学计算机网络笔记(一):初步了解计算机网络
  11. 软件测试周刊(第46期):走好选择的路,别选择好走的路,你才能拥有真正的自己。
  12. Android ScrollView滚动区高度和子LinearLayout的layout_marginTop的关系
  13. 语句摘抄——第13周
  14. 面试官问:MySQL锁与事物隔离级别你知道吗?
  15. 百思不得姐之广告界面(三)
  16. 物质社会会变成巨大的神经,这颗星球将会成一颗会思考的大脑
  17. dom4j 学习 -- 封装dom4j工具类+如何使用dom4j解析
  18. 统计全年12个月数据
  19. python编写等差数列求和_python等差数列求和公式前 100 项的和实例
  20. 预测贷款用户是否会逾期

热门文章

  1. Scrapy学习过程之二:架构及简单示例
  2. 信奥中的数学基础:分解质因数
  3. 机械手编程用c语言,51单片机机械手控制C程序.doc
  4. js-获取JSON数组的长度
  5. 2022-2027年中国化纤行业市场调研及未来发展趋势预测报告
  6. CSP 202112-1 序列查询 python
  7. 初创公司如何选择企业级服务器配置
  8. 还在吐槽翻译的外版书质量差吗?谈谈我个人的理解
  9. 新iPhone9月登场, 5大特色浮出水!
  10. 华为云深度学习kaggle猫狗识别