基于Zynq7000平台VxWorks6.9开发应用——SMP多核任务篇

利用zynq进行AMP和SMP操作系统的学习 之前一直在zynq上裸跑外设,所获有限。不过嘛,最近通过自己的工作可以看到大神的SMP实时操作系统,因此,也萌生了一下自己借助工作平台学习SMP系统自主搭建的念头。不过万丈高楼平地起确实容易塌,因此,一层一层的垒好基础(学习操作系统理论),夯实硬件(理解ARM9原理),才能支撑自己的输出(完成SMP代码)。 首先我们来打一下地基,什么叫SMP操作系统? 说道SMP,就不得不说一下AMP和SMP的区别,zynq作为一个双核平台,同时跑两个工程这种事情,可以通过在建立工程时设置CPU0和CPU1,区... 阅读详情
AI摘要

本文主要讲解在Xilinx ZedBoard上开发基于VxWorks6.9 SMP架构的多核任务调度。介绍了SMP基本概念、系统适配要求及多任务运行实现方法,还说明了创建SMP工程的步骤,以及SMP多核任务机制,包括任务级和中断级CPU Affinity。

 

前言

     本篇文章主要讲解在Xilinx ZedBoard上开发基于VxWorks6.9 SMP架构的多核任务调度,创建两个任务,并分别指定运行在Zynq7000上的两个CortexA9核上,研究多核CPU根据使用场景进行最优化任务部署。本文力求讲述清楚SMP基本概念,以及系统适配SMP模式的要求,SMP模式多任务运行在CPU实现方法,并配套完整的演示软件和相关代码进行验证。下面将从以下几个方面进行讲解。

  1. VxWorks6.9创建SMP模式
  2. 多核任务调度

开发使用工具说明:

  1. WorkBench3.3
  2. ZebBoard开发套件

 

术语和定义

  1. SMP :即对称多处理器(Symmetric Multi-Processing),是指在一个计算机上汇集了一组指令集相同的CPU,各CPU之间共享内存子系统以及总线结构,通常称作为多核CPU系统。
  2. AMP: 即异构多处理器(Asynchronous Multiprocessing),是指在一个计算机上汇集了一组指令集各异、功能各不相同的CPU集合,它们之间通常以松耦合的组织方式联系起来,各自负责处理不同的数据。

 

1、VxWorks6.9 SMP概述

VxWorks SMP是VxWorks的一个配置,设计用于对称多处理(SMP)系统。SMP VxWorks映像提供了与单处理器(UP)配置相同的通用功能。对于对称多处理,操作系统的一个实例控制多个处理单元。这与非对称多处理(AMP)系统不同,在AMP系统中,操作系统的一个单独实例在系统中的每个处理单元上执行。SMP改变了传统的基于优先级的多任务抢占式编程模式,因为它允许多个线程真正并发执行。这是因为操作系统的一个实例运行在并行执行的多个cpu上。当将代码从传统的多任务系统迁移到SMP系统时,必须考虑到这个基本区别。

 

为了运行VxWorks SMP,需要搞清楚以下概念:

(1)多核

系统必须包含至少两个能够完全独立执行的处理单元。

(2)共享内存

每个CPU必须看到完全相同的物理内存子系统。拥有共享内存意味着,在访问内存时,系统上执行的代码不需要考虑是哪个CPU在执行代码。也就是说,不像在松散耦合的多处理系统中那样,CPU的内存是本地的。

(3)原子操作

cpu必须能够使用内存位置上的原子操作彼此同步。这种能力是构建自旋锁的基础。自旋锁是SMP系统中重要的同步和互斥机制。

(4)缓存一致性

假设每个CPU都有一个或多个专用缓存,硬件必须保持这些缓存之间的一致性。这对于数据缓存尤其重要——对于指令缓存则不那么重要。如果在不同CPU上的不同数据缓存中的两个数据缓存线指向相同的内存位置,硬件应该管理这些缓存线的状态,以便每个CPU获得正确的值。如果一个CPU将一条线刷新到内存中,那么所有引用相同位置的其他缓存线都必须自动更新(无效,或刷新,取决于一致性算法)。

(5)一种cpu间中断的机制

处理器必须支持一个CPU中断另一个CPU的能力。这通常是通过全局中断控制器设备来完成的(参见配置中断控制器驱动程序)。必须有一种方法将处理器间中断(IPIs)设置为优先级高于所有其他中断。此外,根据目标硬件的不同,可以访问所有cpu的设备。也就是说,每个CPU应该能够访问所有设备,并且能够通过一个全局可编程中断控制器将这些设备的中断路由到任何一个CPU。

对称多处理(SMP)系统开发,建议使用vxbus的设备驱动程序。风河不提供SMP安全的遗留模型驱动程序。如果希望在SMP系统中使用遗留模型设备驱动程序,则必须确保该驱动程序是SMP安全的。

 

2、VxWorks6.9创建SMP工程

利用WorkBench3.3工作台创建一个SMP BSP项目:

(1)创建一个VxWorks映像项目(File>New->Project)

(2)在项目设置对话框中,单击BSP列表旁边的Browse按钮,浏览到您的BSP目录。

(3)在Options对话框中,选择内核中的SMP支持。

 

VxWorks SMP内核相关配置如表1所示。

 

表1  VxWorks SMP相关配置宏

WRS_CONFIG_SMP

Configuration

Kernel libraries have been built with SMP support.

VX_SMP_NUM_CPUS

Parameter

Number of CPUs assigned to run the SMP image.

INCLUDE_SMP_DEMO

Component

Include SMP demo code in the image.

 

 

 

3、SMP多核任务机制

VxWorks SMP提供了CPU Affinity这种机制。通过这种机制可以将中断或者任务分配给指定的CPU执行。

(1)任务级 CPU Affinity

VxWorks SMP 具有将任务分配给指定 CPU 执行的能力。从另一个角度来说,即将指定CPU 预留给指定任务。

SMP 的默认操作——任何任务可以运行在任何 CPU 上——这会根据系统的整体性能而定。但是有些时候将指定任务分配给指定的 CPU 对系统性能是有帮助的。例如一个CPU上只运行一个单独的任务而不做其他事情,则这块 CPU 的 cache 中就只保存了这个任务所需要的数据和代码。这样做节省了任务在 CPU 之间切换的消耗。

当多个任务争夺一个spinlock时,如果这些任务运行在不同的CPU上,则会有大量的时间被浪费在等待spinlock上。若将争夺同一个 spinlock 的任务指定在同一个CPU 上运行,则这会给另一块 CPU 上执行其他程序带来便利。

关于任务级 CPU affinity 的使用方法如下:

a. 一个任务可以通过调用 taskCpuAffinitySet()设置自己的 CPU affinity,也可以设置其他任务的 CPU affinity;

b. 子任务会继承父任务的CPU affinity。一个任务中调用如下API就会自动继承CPUaffinity: taskSpawn(), taskCreate(), taskInit(), taskOpen(), taskInitExcStk()。任务级 CPU affinity 的 API 如表 2 所示。

表2 任务级CPU affinity API

API

描述

STATUS taskCpuAffinitySet(int tid,  cpuset_t newAffinity)

分配一个任务在指定 CPU 上执行。

STATUS taskCpuAffinityGet(int tid, cpuset_t* pAffinity)

获得指定任务在哪个 CPU 上执行。

taskCpuAffinitySet()和 taskCpuAffinityGet()都使用cpuset_t结构对CPU 信息进行标示。前者用于分配任务到指定 CPU;后者获取指定任务的cpu_set_t。CPUSET_ZERO()宏定义用于将 cpuset_t 清0(类似FD_ZERO),它必须被最先调用。CPUSET_SET()宏定义在 CPUSET_ZERO()之后使用。

 

任务级 CPU Affinity 示例:

#include <vxWorks.h>

#include <vsbConfig.h>

#include <stdio.h>

#include <tickLib.h>

#include <string.h>

#include <stdlib.h>

#include <eventLib.h>

#include <taskLib.h>

#include <vxLib.h>

#include <fioLib.h>     /* fioRdString */

 

#ifdef _WRS_CONFIG_SMP

#include <private/cpcLibP.h>

#include <logLib.h>

#include <cpuset.h>

#include <vxCpuLib.h>

#endif

 

static  void myCpu0Task(void)

{

    int a = 0;

 

    while(1)

    {

        a++;

        printf ("\n myCpu0Task running %d times on cpu%d\n", a, vxCpuIndexGet());   

        taskDelay(60);;

    }

}

 

static  void myCpu1Task(void)

{

    int b = 0;

 

    while(1)

    {

        b++;

        printf ("\n myCpu1Task running %d times on cpu%d\n", b, vxCpuIndexGet());   

        taskDelay(120);;

    }

}

 

 

int affinityTaskDemo(void)

{

    TASK_ID tid1, tid2;

    cpuset_t affinity1, affinity2;

   

   

    /* Create the task1 but only activate it after setting its affinity */

    tid1 = taskCreate ("Cpu0Task", 100, 0, 5000, (FUNCPTR)myCpu0Task, 0, 0, 0, 0,

              0, 0, 0, 0, 0, 0);

    if (tid1 == (TASK_ID)NULL)

        return ERROR;

   

    /* Clear the affinity1 CPU set and set index for CPU 0 */

    CPUSET_ZERO(affinity1);

    CPUSET_SET(affinity1, 0);

   

    if (taskCpuAffinitySet(tid1, affinity1) == ERROR)

    {

        taskDelete(tid1);

        return ERROR;

    }

   

    /* Now let the task run on CPU 0 */

    taskActivate(tid1);

   

 

    /* Create the task2 but only activate it after setting its affinity */

    tid2 = taskCreate ("Cpu1Task", 100, 0, 5000, (FUNCPTR)myCpu1Task, 0, 0, 0, 0,

              0, 0, 0, 0, 0, 0);

    if (tid2 == (TASK_ID)NULL)

        return ERROR;

   

    /* Clear the affinity2 CPU set and set index for CPU 2 */

    CPUSET_ZERO(affinity2);

    CPUSET_SET(affinity2, 1);

   

    if (taskCpuAffinitySet(tid2, affinity2) == ERROR)

    {

        taskDelete(tid2);

        return ERROR;

    }

   

    /* Now let the task run on CPU 1 */

    taskActivate(tid2);

   

    return OK;

}

 

上述SMP多核任务示例代码运行结果如下,可见结果符合预期。

myCpu0Task running 1 times on cpu0

myCpu0Task running 2 times on cpu0

myCpu1Task running 2 times on cpu1

myCpu0Task running 3 times on cpu0

myCpu0Task running 4 times on cpu0

myCpu1Task running 3 times on cpu1

myCpu0Task running 5 times on cpu0

myCpu0Task running 6 times on cpu0

myCpu1Task running 4 times on cpu1

myCpu0Task running 7 times on cpu0

myCpu0Task running 8 times on cpu0

myCpu1Task running 5 times on cpu1

myCpu0Task running 9 times on cpu0

myCpu0Task running 10 times on cpu0

myCpu1Task running 6 times on cpu1

myCpu0Task running 11 times on cpu0

myCpu0Task running 12 times on cpu0

myCpu1Task running 7 times on cpu1

myCpu0Task running 13 times on cpu0

 

(2)中断级 CPU Affinity

SMP硬件需要可编程中断控制设备。VxWorks SMP利用这些硬件可以分配中断到指定CPU。默认情况下,中断是在VxWorks的CPU 0中触发的。

通过中断级 CPU Affinity,可以将中断合理平均的分配到不同 CPU 上(而不是在一个CPU 上存在很多中断)。

运行时刻分配中断到指定CPU是在启动时发生的,当系统启动从 BSP 中读取中断配置信息的时候。中断控制器收到一条命令,该命令用于指示一条中断运行在指定的CPU上。

该小节内容将在后续的篇章里面详细介绍。

基于zynq7000平台的vxWorks6.9移植(上) 编写本文档的目的在于指导用户如何移植基于z7平台的vxWorks6.9系统。分上下两篇,帮助新手可以独立完成。 阅读详情

相关推荐

Zynq7000平台VxWorks6.9 SMP实战:多核任务调度与CPU亲和性深度解析

我在ZedBoard上实测发现,当运行VxWorks6.9 SMP模式时,两个CPU核心默认采用共享任务队列的调度方式,这会导致计算密集型任务和I/O任务相互干扰。但要注意VxWorks6.9的SMP实现有个特殊限制:所有中断默认由核心0处理,需要手动配置才能启用核心1的中断处理能力。但要注意,过度绑定会导致核心利用率不均衡,我在某次项目中就遇到过核心0满载而核心1闲置30%的情况。在Zynq7000平台上,我还遇到过因为PL(可编程逻辑)中断未正确绑定核心,导致DMA传输不稳定的问题。

weixin_42556197的博客 423

VxWorks在Zynq平台上的移植详细流程

详细介绍了VxWorks移植到Zynq平台,包括bootrom和内核(vxWorks、vxworks.sym),通过QSPI启动bootrom,文件系统(TFFS)挂载到EMMC中,以及调试EMMC驱动,以及应用程序的开发

告别任务打架!在Zynq7000上用VxWorks6.9 SMP实现任务与CPU的精准绑定

本文详细介绍了如何在Zynq7000双核平台上使用VxWorks6.9 SMP实现任务与CPU的精准绑定,解决多核任务调度中的'任务打架'问题。通过分析Zynq7000 SMP架构特性、VxWorks API解析及实战案例,帮助开发者优化系统性能,提升任务执行效率。

weixin_42544461的博客 207

VxWorks之SMP多核编译 配置

smp在vxworks里面是很重要的部分,如果没有配置这个在设计到smp编译器的时候也会出现smp等于1的然后运行DKM工程不成功等现象。smp的配置在创建vip工程的时候配置的:这一步很重要 这里如果没有选择后面程序不能运行。OS运行在多个处理单元上,并且内存是共享的。最近在调试vxworks的系统,在这里记录一下smp。选择相应的编译器,然后配置编译器。我这里使用的是NFS的方式挂载。关于VxWorks SMP。SMP是多核技巧中的一。然后编辑c文件编译执行。后续更新》》》》》》》

Cfx1998的博客 1038

Zynq7000双核实战:手把手教你用VxWorks6.9和WorkBench3.3实现任务绑定CPU

本文详细介绍了如何在Zynq7000双核系统上使用VxWorks6.9和WorkBench3.3实现任务绑定CPU的实战方法。通过环境配置、SMP原理讲解、代码示例和调试技巧,帮助开发者充分利用双核优势,提升嵌入式系统的并行计算性能。重点介绍了任务绑定API的使用和优化建议。

weixin_42524824的博客 385

从AMP到SMP:手把手教你将ZedBoard上的VxWorks6.9项目升级为多核模式

本文详细介绍了如何将ZedBoard上的VxWorks6.9项目从AMP模式升级为SMP多核模式,涵盖SMP架构的核心价值、WorkBench3.3环境配置、代码迁移技巧及性能调优策略。通过实战案例展示如何解决多核任务调度、共享资源竞争等关键问题,帮助开发者充分利用Zynq7000双核Cortex-A9的性能潜力。

weixin_28731223的博客 397

taskset设置CPU affinity

Retrieve or set a processes's CPU affinity(亲和). This requires sched_{g,s}etaffinity support in your libc. 1.busybox cd ~/source-code/mc40/buildroot-2020.02.8 make busybox-menuconfig Linux System Utilities---> [*] taskset (4.2...

ARM-Linux 1552

从AMP到SMP:在ZedBoard上用VxWorks6.9搞懂多核编程的两种玩法与选择

本文深入探讨了在ZedBoard平台上使用VxWorks6.9实现多核编程的两种架构:SMP和AMP。通过对比分析Zynq7000双核Cortex-A9在两种模式下的内存管理、任务调度和中断响应等关键特性,为工业控制和边缘计算项目提供技术选型指南。文章包含实战代码示例和性能数据,帮助开发者在实时性和灵活性之间做出最优决策。

weixin_28732953的博客 421

VxWorks6.9 SMP模式下的性能调优:从任务乱跑到CPU亲和性,聊聊Zynq7000多核设计的那些事儿

本文深入探讨了VxWorks6.9在Zynq7000多核平台上的SMP性能调优策略,重点分析了任务调度中的缓存颠簸和锁竞争问题,并详细介绍了CPU亲和性技术的实战应用。通过优化任务分配和中断处理,显著提升了Zynq7000双核系统的整体性能,为嵌入式多核设计提供了宝贵经验。

weixin_30680385的博客 325

Zynq7000双核实战:手把手教你用VxWorks6.9把两个任务‘钉’在不同CPU上

本文详细介绍了如何在Zynq7000双核处理器上使用VxWorks6.9实现任务绑定到不同CPU核心的实战方法。通过SMP支持配置、CPU亲和性API使用及完整代码示例,帮助开发者充分利用多核性能优势,提升嵌入式系统效率。

weixin_33691700的博客 243

xilinx zynq ps端移植vxworks6.9系统

基于a board support package,选择xlnx_zynq7k BSP,编译工具链选择diab,勾选Enable WDB Target Agent,选择next下一步,VxWorks Image Project Multipage Wizard就配置完成。从the New VxWorks Image Project中,profile选择PROFILE_DEVELOPMENT,单击finish。project中选择open development shell打开vxworks脚本编译窗口。

wangjie36的博客 5594

VxWorks SMP多核编程指南.doc

VxWorks SMP多核编程指南.doc

第四课:创建VxWorks系统镜像

VxWorks6.9内核与BSP开发详解

smartvxworks的博客 1902

在ZedBoard上玩转VxWorks6.9:手把手教你用CPU Affinity把任务‘钉’在指定核上

本文详细介绍了在ZedBoard上使用VxWorks6.9的CPU Affinity功能,将任务固定在指定核上的实战技巧。通过SMP环境搭建、核心API解析和双核负载均衡方案,帮助开发者优化Zynq7000平台的多核性能,提升系统响应速度和缓存命中率。

weixin_42535461的博客 346

第五课:创建DownLoadable系统应用

VxWorks6.9内核与BSP开发详解

smartvxworks的博客 1087

VxWorksSMP多核编程指南.pdf

VxWorks多核编程 SMP amp 介绍非常详细,上手即用。非常适合想要了解VxWorks多核编程的各位;

vxWorks SMP 多核编程

多核编程指南 vxworks_kernel_programmers_guide_6.8 第24章 介绍 是风河公司为VxWorks设计的symmetric multiprocessing(SMP)系统。 uniporcessor(UP)系统一样,具备实时操作系统的特性。 VxWorks SMP系统的特点。介绍了VxWorks SMP的配置过程、它 UP编程...

m0_37585897的博客 5082

GNSS/INS松组合导航实战:如何用卡尔曼滤波提升定位精度(附MATLAB代码)

本文深入探讨了GNSS/INS松组合导航的工程实践,详细阐述了如何利用卡尔曼滤波算法融合卫星与惯性数据以提升定位精度。内容涵盖从仿真环境搭建、误差状态卡尔曼滤波器(ESKF)设计,到状态与观测方程实现、噪声参数调试及常见问题排查的全过程,并提供了可直接运行的MATLAB代码,为开发高精度、鲁棒的组合导航系统提供实战指南。

weixin_29057163的博客 162
上一篇: 基于Zynq7000平台VxWorks6.9开发应用——PS与PL通信 BRAM应用篇
下一篇: VMware下Ubuntu系统扩展硬盘方法
CPUOS2010
博客等级 码龄5年 88粉丝 33原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CPUOS2010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值