【条记】基于ARM多核架构的项目总结:共享内存、核间通讯与多核调理分析 ...

打印 上一主题 下一主题

主题 1017|帖子 1017|积分 3051

1:前言

由于在项目中有所接触到相关的多核调理以及共享内存、核间通讯等方面的知识,因此本篇条记用来记录项目调试过程中所遇到一些问题与思考。
本篇条记是通过学习
        1:《ARM® Generic Interrupt Controller Architecture Specification - GIC architecture version 3.0 and version 4.0》
        2:嵌入式中的多核开辟和核间通讯总结_核间通讯-CSDN博客
        3:[条记] GICv3/v4 ITS 与 LPI_gic lpi-CSDN博客
所做的条记
2:共享内存

  2.1基本定义

共享内存是一种高效的进程间通讯(IPC)机制,允许多个进程直接访问同一块物理内存区域。通过共享内存,多个进程可以在内存中共享数据,而无需通过内核进行中转,从而避免了数据复制和系统调用的开销。这种机制使得数据在多个进程之间可以或许快速传递,是进程间通讯中速率最快的方式。 
  2.2 工作原理

共享内存的工作原理基于操作系统的内存管理机制。具体步调如下:

  • 创建共享内存:操作系统在物理内存中分配一个共享内存段。
  • 映射共享内存:各个进程通过特定的标识符访问同一块共享内存空间,并将其映射到本身的虚拟所在空间。
  • 数据访问:进程可以直接对映射后的内存区域进行读写操作,其他进程可以或许即时看到这些改动。
  • 销毁共享内存:当共享内存不再需要时,进程会解除映射并销毁共享内存
3:核间通讯(IPC)

  3.1基础定义

核间通讯(Inter-Processor Communication,IPC)是指在多核系统中,不同处理器焦点之间进行数据传递和同步的机制。其目的是为了在多核架构中实现高效的相助与资源共享,使各个焦点可以或许协同完成复杂的使命。
  3.2数据同等性

在核间通讯中一般利用下列方法进行数据同等性的包管:
        1. 利用锁机制

锁是确保数据同等性最常用的方法之一。在多核系统中,锁可以防止多个焦点同时访问共享数据,从而避免数据竞争。
互斥锁(Mutex):互斥锁可以确保同一时间只有一个焦点可以访问共享数据。在访问共享数据之前,焦点需要获取锁,访问完成后释放锁。
自旋锁(Spinlock):自旋锁是一种忙等待锁,适用于短时间的锁定操作。在多核系统中,自旋锁可以快速掩护共享数据,防止多个焦点同时写入。
读写锁(Read-Write Locks):假如共享数据的读操作远多于写操作,利用读写锁可以提高效率。读写锁允许多个读操作同时进行,但写操作需要独占。
        2. 内存屏障

内存屏障(Memory Barrier)是一种同步机制,用于确保内存操作的顺序性,防止编译器和处理器对内存操作进行重排序。
编译器屏障:防止编译器对代码进行优化重排序。
CPU内存屏障:防止CPU对内存操作进行乱序实验。
        3. 利用共享内存掩护机制

在利用共享内存进行核间通讯时,必须采取措施掩护共享内存中的数据。
关闭全局中断:在访问共享内存时,通过关闭全局中断来防止其他焦点的中断处理步伐访问共享数据。
利用自旋锁掩护共享内存:在访问共享内存时,利用自旋锁来掩护数据,确保同一时间只有一个焦点可以访问。
4:多核调理

在不同的实时操作系统(RTOS)中,提供的底层接口可能无法完全满意项目需求。比方,你可能需要同时调理核0到核3的GICD_ISENABLER寄存器,但现有的底层接口可能仅支持使能当前核的GICD_ISENABLER寄存器。在这种情况下,为了满意需求,就需要对底层接口进行改写和优化,以实现对多个核的寄存器操作。

下面分享一个代码思绪
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. //根据芯片手册决定base地址以及不同核之间寄存器间隔为多少
  4. #define GICD_BASE 0x10000000
  5. #define GICD_ISENABLER_OFFSET 0x100
  6. #define Register_Interval_Address 0x1000
  7. // 定义一个函数来使能指定中断号的中断
  8. void enable_interrupt(uint32_t core_num, uint32_t interrupt_id, uint32_t core_mask) {
  9.     uint32_t* gicd_isenabler = (uint32_t*)(GICD_BASE + GICD_ISENABLER_OFFSET);
  10.     // 遍历所有核心,使能指定的中断
  11.     for (uint32_t core_id = 0; core_id < core_num; core_id++) {
  12.         if (core_mask & (1 << core_id)) {
  13.             // 计算当前核心的 GICD_ISENABLER 寄存器地址
  14.             uint32_t* core_isenabler = gicd_isenabler + (core_id * Register_Interval_Address );  
  15.             // 使能指定的中断
  16.             *core_isenabler |= (1 << interrupt_id);
  17.             printf("Core %d: Interrupt %d enabled\n", core_id, interrupt_id);
  18.         }
  19.     }
  20. }
  21. int main() {
  22.     //假设一共有4个核
  23.     uint32_t core_mask = 0b1111;
  24.     // 使能中断号为5的中断
  25.     enable_interrupt(4, 5, core_mask);
  26.     return 0;
  27. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

尚未崩坏

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表