OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 1437|回复: 4

[XILINX] zynq amp架构双裸核通信,cpu1无法进入中断

[复制链接]

30

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2020-10-19
在线时间
54 小时
发表于 2024-1-2 16:48:16 | 显示全部楼层 |阅读模式
根据提供的例程,实现了amp架构下双裸核呼吸灯频率控制。现在想在此基础上测试,两个cpu之间64KB的通信测试。
遇到的问题是,在例程模板下,修改了功能代码后,cpu1无法进入中断。利用条件宏切换了功能,验证了中断的代码是正确的(相应的代码就没有动过)。DDR和OCM也确认了配置没有任何问题。不清楚为什么cpu1没有进入中断。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

30

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2020-10-19
在线时间
54 小时
 楼主| 发表于 2024-1-3 16:15:31 | 显示全部楼层
昨天尝试了一下加入延时,虽然能够实现进入软中断,但由于要测试核间利用OCM的通信速率,测试结果为6Mbps。并且时间上还和延时有关,低于80ms,cpu1就无法进入中断。这种方式应该是不太对的。所以问题并没有解决。这是我的代码,望有大佬出没,能帮忙看看具体是哪里出了问题。

  1. #include "xparameters.h"
  2. #include "xscugic.h"
  3. #include "xil_printf.h"
  4. #include "xil_exception.h"
  5. #include "xil_mmu.h"
  6. #include "stdio.h"

  7. #include <string.h>
  8. #include <stdint.h>
  9. #include <stdlib.h>
  10. #include <sleep.h>
  11. #include <time.h>

  12. //宏定义
  13. #define INTC_DEVICE_ID             XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID
  14. #define SHARE_BASE           0xffff0000                   //共享OCM首地址
  15. #define CPU1_START_ADDR      0xfffffff0                   //CPU1开始地址
  16. #define CPU1_START_MEM       0x10000000                   //CPU1程序开始地址
  17. #define CPU1_ID              XSCUGIC_SPI_CPU1_MASK   //CPU1 ID,0bxxxxxx1x指向CPU1

  18. //"SEV"指令唤醒CPU1并跳转至相应的程序
  19. #define sev()                __asm__("sev")

  20. //堆空间开辟长度64KB(16384*4)
  21. #define ALLOCATE_HEAP_SPACE  16384

  22. //函数声明
  23. void start_cpu1();
  24. void cpu0IntrInit(XScuGic *intc_ptr);
  25. void IntrHandler(void *CallbackRef);

  26. //全局变量
  27. XScuGic Intc;                    //中断控制器驱动
  28. volatile int rec_intr_flag = 0;           //接收到来自cpu1中断的标志

  29. //软件中断号
  30. u16 SoftIntrIdToCpu0 = 0 ;
  31. u16 SoftIntrIdToCpu1 = 1 ;

  32. //CPU0 main函数
  33. int main()
  34. {
  35.         //用于验证cpu0是否成功发送软中断给cpu1
  36.         uint32_t u32SoftIntrFlag = 1;

  37.         //开辟64KB堆空间并初始化
  38.         uint32_t* pu32HeapSpace = (uint32_t*)calloc(ALLOCATE_HEAP_SPACE,sizeof(uint32_t));
  39.         if(NULL != pu32HeapSpace)
  40.         {
  41.                 for(uint32_t i = 0; i < ALLOCATE_HEAP_SPACE; i++)
  42.                 {
  43.                         pu32HeapSpace[i] = i;
  44.                 }
  45.                 xil_printf("Heap initialization is complete! \r\n");
  46.         }
  47.         else
  48.         {
  49.                 xil_printf("Allocate Heap Space is failed.\r\n");
  50.                 return 1;
  51.         }

  52.         //复位使用的OCM空间
  53.         uint32_t* pToOCM = (uint32_t*)SHARE_BASE;
  54.         memset(pToOCM, 0, sizeof(ALLOCATE_HEAP_SPACE));

  55.         //禁用Cache缓存
  56.         Xil_SetTlbAttributes(SHARE_BASE,0x14de2);

  57.         //禁用 0xfffffff0 的 Cache 属性
  58.         Xil_SetTlbAttributes(CPU1_START_ADDR,0x14de2);

  59.         //启动CPU1
  60.         start_cpu1();

  61.         //CPU0中断初始化
  62.         cpu0IntrInit(&Intc);

  63.         while(1)
  64.         {
  65.                 if(rec_intr_flag == 0)
  66.                 {
  67.                         xil_printf("CPU0: Prepare to Write Heap Data to COM. \r\n");

  68.                         //将参数写入共享的内存
  69.                         for(uint32_t j = 0; j < ALLOCATE_HEAP_SPACE; j++)
  70.                         {
  71.                                 Xil_Out32((SHARE_BASE + j*4),pu32HeapSpace[j]);
  72.                         }
  73.                         xil_printf("CPU0: Write Complete. \r\n");
  74. //                        free(pu32HeapSpace);
  75.                         xil_printf("\r\n");

  76. Again:
  77.                         usleep(80*1000); //延时100ms

  78.                         //给CPU1发送软件中断
  79.                         u32SoftIntrFlag = XScuGic_SoftwareIntr(&Intc,SoftIntrIdToCpu1,CPU1_ID);
  80.                         if(XST_SUCCESS == u32SoftIntrFlag)
  81.                         {
  82.                                 xil_printf("CPU0: SoftwareInter to CPU1 is success! \r\n");
  83.                                 rec_intr_flag = 1;
  84.                         }
  85.                         else
  86.                         {
  87.                                 xil_printf("CPU0: Retry to SoftwareInter to CPU1! \r\n");
  88.                                 goto Again;
  89.                         }
  90.                 }
  91.         }
  92.         return 0 ;
  93. }

  94. //启动CPU1
  95. void start_cpu1()
  96. {
  97.         //向 CPU1_START_ADDR(0Xffffffff0)地址写入 CPU1 的访问内存基地址
  98.         Xil_Out32(CPU1_START_ADDR, CPU1_START_MEM);
  99.         dmb();
  100.         sev();  //唤醒CPU1并跳转至相应的程序
  101. }

  102. //CPU0中断初始化
  103. void cpu0IntrInit(XScuGic *intc_ptr)
  104. {
  105.         //初始化中断控制器
  106.         XScuGic_Config *intc_cfg_ptr;
  107.         intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
  108.     XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,
  109.                     intc_cfg_ptr->CpuBaseAddress);

  110.     //设置并打开中断异常处理功能
  111.     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
  112.                     (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);
  113.     Xil_ExceptionEnable();
  114.     //关联中断源及中断处理函数
  115.     XScuGic_Connect(intc_ptr, SoftIntrIdToCpu0,
  116.           (Xil_ExceptionHandler)IntrHandler, (void *)intc_ptr);

  117.     XScuGic_Enable(intc_ptr, SoftIntrIdToCpu0); //CPU0软件中断
  118. }

  119. //中断服务函数
  120. void IntrHandler(void *CallbackRef)
  121. {
  122.         xil_printf("This is CPU0,Receive software interrupt from CPU1\r\n");
  123.         xil_printf("\r\n");
  124.         rec_intr_flag = 0;
  125. }
  126. 以上是cpu0.c

  127. /*
  128. * Arm1.c
  129. *
  130. *  Created on: 2023年12月29日
  131. *      Author: yuan.lv
  132. */


  133. #include "xparameters.h"
  134. #include "xscugic.h"
  135. #include "xil_printf.h"
  136. #include "xil_exception.h"
  137. #include "xil_mmu.h"
  138. #include "stdio.h"

  139. //宏定义
  140. #define INTC_DEVICE_ID             XPAR_SCUGIC_SINGLE_DEVICE_ID //中断ID
  141. #define SHARE_BASE               0xffff0000                   //共享OCM首地址
  142. #define CPU0_ID              XSCUGIC_SPI_CPU0_MASK        //CPU1 ID,0bxxxxxxx1指向CPU0

  143. //堆空间开辟长度64KB(16384*4)
  144. #define ALLOCATE_HEAP_SPACE  16384

  145. //函数声明
  146. void cpu1IntrInit(XScuGic *intc_ptr);
  147. void IntrHandler(void *CallbackRef);

  148. //全局变量
  149. XScuGic Intc;               //中断控制器驱动
  150. volatile int intr_flag = 0;          //软件中断的标志

  151. //软件中断号
  152. u16 SoftIntrIdToCpu0 = 0 ;
  153. u16 SoftIntrIdToCpu1 = 1 ;


  154. //CPU1 main函数
  155. int main()
  156. {
  157.         //存储从ocm中读出的数据
  158.         volatile uint32_t u32ReadData = 0;

  159.         //禁用Cache缓存
  160.         Xil_SetTlbAttributes(SHARE_BASE,0x14de2);

  161.         //CPU1中断初始化
  162.         cpu1IntrInit(&Intc);

  163.         while(1)
  164.         {
  165.                 if(intr_flag)
  166.                 {
  167.                         xil_printf("CUP1: Prepare to Read Data from COM. \r\n");
  168.                         for(uint32_t i = 0; i < ALLOCATE_HEAP_SPACE; i++)
  169.                         {
  170.                                 u32ReadData = Xil_In32(SHARE_BASE + i*4);     //从共享内存中读出数据
  171.                                 xil_printf("CPU1: Read Data [No.%d  0x%x] \r\n", i, u32ReadData);
  172.                         }
  173.                         xil_printf("CUP1: Read Complete. \r\n");
  174.                         xil_printf("\r\n");

  175.                         //给CPU0发送软件中断
  176.                         XScuGic_SoftwareIntr(&Intc,SoftIntrIdToCpu0,CPU0_ID);
  177.                         intr_flag = 0;
  178.                 }
  179.         }
  180.         return 0 ;
  181. }

  182. //CPU1中断初始化
  183. void cpu1IntrInit(XScuGic *intc_ptr)
  184. {
  185.         //初始化中断控制器
  186.         XScuGic_Config *intc_cfg_ptr;
  187.         intc_cfg_ptr = XScuGic_LookupConfig(INTC_DEVICE_ID);
  188.     XScuGic_CfgInitialize(intc_ptr, intc_cfg_ptr,
  189.                     intc_cfg_ptr->CpuBaseAddress);
  190.     //设置并打开中断异常处理功能
  191.     Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
  192.                     (Xil_ExceptionHandler)XScuGic_InterruptHandler, intc_ptr);
  193.     Xil_ExceptionEnable();
  194.     //关联中断源及中断处理函数
  195.     XScuGic_Connect(intc_ptr, SoftIntrIdToCpu1,
  196.           (Xil_ExceptionHandler)IntrHandler, (void *)intc_ptr);

  197.     XScuGic_Enable(intc_ptr, SoftIntrIdToCpu1); //使能CPU1软件中断
  198. }

  199. //中断服务函数
  200. void IntrHandler(void *CallbackRef)
  201. {
  202.         xil_printf("This is CUP1,Soft Interrupt from CPU0\r\n") ;
  203.         intr_flag = 1;
  204. }
  205. 以上是cpu1.c
复制代码
回复 支持 反对

使用道具 举报

3

主题

2012

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
5615
金钱
5615
注册时间
2018-10-21
在线时间
1590 小时
发表于 2024-1-5 17:56:40 | 显示全部楼层
传的数据有没有超过OCM的最大存储容量
回复 支持 反对

使用道具 举报

30

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2020-10-19
在线时间
54 小时
 楼主| 发表于 2024-1-8 09:11:11 | 显示全部楼层
QinQZ 发表于 2024-1-5 17:56
传的数据有没有超过OCM的最大存储容量

没有超过,就是64KB,我也尝试过减小数据量,如果不加延时也是不行。
回复 支持 反对

使用道具 举报

30

主题

71

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2020-10-19
在线时间
54 小时
 楼主| 发表于 2024-1-11 14:00:08 | 显示全部楼层
问题已解决,需要延时的地方是在Start_CPU1( );后面。个人理解的是,两个核毕竟是各自独立运行,以至于不加延时时,CPU1的中断函数还没有启动,导致CPU0发出去软中断后,CPU1没办法立刻做出回应!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 11:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表