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

2023-11-11 23:21

本文主要是介绍基于Zynq7000平台VxWorks6.9开发应用——SMP多核任务篇,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

前言

     本篇文章主要讲解在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开发应用——SMP多核任务篇的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/393505

相关文章

基于Python开发Windows屏幕控制工具

《基于Python开发Windows屏幕控制工具》在数字化办公时代,屏幕管理已成为提升工作效率和保护眼睛健康的重要环节,本文将分享一个基于Python和PySide6开发的Windows屏幕控制工具,... 目录概述功能亮点界面展示实现步骤详解1. 环境准备2. 亮度控制模块3. 息屏功能实现4. 息屏时间

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

使用Python开发一个现代化屏幕取色器

《使用Python开发一个现代化屏幕取色器》在UI设计、网页开发等场景中,颜色拾取是高频需求,:本文主要介绍如何使用Python开发一个现代化屏幕取色器,有需要的小伙伴可以参考一下... 目录一、项目概述二、核心功能解析2.1 实时颜色追踪2.2 智能颜色显示三、效果展示四、实现步骤详解4.1 环境配置4.

Python使用smtplib库开发一个邮件自动发送工具

《Python使用smtplib库开发一个邮件自动发送工具》在现代软件开发中,自动化邮件发送是一个非常实用的功能,无论是系统通知、营销邮件、还是日常工作报告,Python的smtplib库都能帮助我们... 目录代码实现与知识点解析1. 导入必要的库2. 配置邮件服务器参数3. 创建邮件发送类4. 实现邮件

Python使用Tkinter打造一个完整的桌面应用

《Python使用Tkinter打造一个完整的桌面应用》在Python生态中,Tkinter就像一把瑞士军刀,它没有花哨的特效,却能快速搭建出实用的图形界面,作为Python自带的标准库,无需安装即可... 目录一、界面搭建:像搭积木一样组合控件二、菜单系统:给应用装上“控制中枢”三、事件驱动:让界面“活”

基于Python开发一个有趣的工作时长计算器

《基于Python开发一个有趣的工作时长计算器》随着远程办公和弹性工作制的兴起,个人及团队对于工作时长的准确统计需求日益增长,本文将使用Python和PyQt5打造一个工作时长计算器,感兴趣的小伙伴可... 目录概述功能介绍界面展示php软件使用步骤说明代码详解1.窗口初始化与布局2.工作时长计算核心逻辑3

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹