TriCore: 从RTOS内核的角度看CSA

news2024/11/25 2:41:34

今天尝试从RTOS内核的角度来看看 TriCore 的 CSA。

CSA的细节信息可以参考前一篇文章 TriCore User Manual 笔记 1-CSDN博客

CSA 的全称是 Context Save Area,顾名思义就是专门用来保存上下文的一块存储区域。

既然是上下文使用,那必然要求低延迟,因此一般将其部署在 fast ram 区域,具体到 TriCore 中,一般将其置于 DSPR 区域。在使用时,在内核启动之前,要将用作 CSA 的内存区域进行初始化,将其串成一个 Free CSA List,并将该区域的首尾地址分别赋值给 FCX 和 LCX 两个 CSA 寄存器,保证程序运行时能正常通过两个寄存器使用 Free CSA List。然后在创建任务时,为每个任务分配初始 CSA,保存任务初始运行状态信息。

下面,结合 Aurix Studio IDE 和 FreeRTOS 来看下上面所说的每一步分别怎么实现。

1. 部署 csa,放置到 DSPR 区域

#define LCF_DSPR0_SIZE  240k
#define LCF_CSA0_OFFSET     (LCF_DSPR0_SIZE - 1k - LCF_CSA0_SIZE)
     

    memory dsram0 // Data Scratch Pad Ram
    {
        mau = 8;
        size = 240k;
        type = ram;
        map (dest=bus:tc0:fpi_bus, dest_offset=0xd0000000, size=240k, priority=8);
        map (dest=bus:sri, dest_offset=0x70000000, size=240k);
    }
 
    group (ordered)
    {
         // 将 CORE0 CSA  部署到 DSPR 区域
         group (align = 64, attributes=rw, run_addr=mem:dsram0[LCF_CSA0_OFFSET]) 
         reserved "csa_tc0" (size = LCF_CSA0_SIZE);
         "__CSA0":=        "_lc_ub_csa_tc0";
         "__CSA0_END":=    "_lc_ue_csa_tc0";
    }

2. 初始化 CSA, 创建 Free CSA List,并初始化 FCX 和 LCX 寄存器

    #define IFX_SSW_INIT_CONTEXT()                                                   \
    {                                                                            \
        /* Load user stack pointer */                                            \
        Ifx_Ssw_setAddressReg(a10, __USTACK(0));                                 \
        Ifx_Ssw_DSYNC();                                                         \
                                                                                 \
        /*Initialize the context save area for CPU0. Function Calls Possible */  \
        /* Setup the context save area linked list */                            \
        Ifx_Ssw_initCSA((unsigned int *)__CSA(0), (unsigned int *)__CSA_END(0)); \
        /* Clears any instruction buffer */                                      \
        Ifx_Ssw_ISYNC();                                                         \
    }


IFX_SSW_INLINE void Ifx_Ssw_initCSA(unsigned int *csaBegin, unsigned int *csaEnd)
{
    unsigned int  k;
    unsigned int  nxt_cxi_val = 0U;
    unsigned int *prvCsa      = 0U;
    unsigned int *nxtCsa      = csaBegin;
    unsigned int  numOfCsa    = (((unsigned int)csaEnd - (unsigned int)csaBegin) / 64U);

    for (k = 0U; k < numOfCsa; k++)
    {
        nxt_cxi_val = ((unsigned int)((unsigned int)nxtCsa & ((unsigned int)0XFU << 28U)) >> 12U) | \
                      ((unsigned int)((unsigned int)nxtCsa & ((unsigned int)0XFFFFU << 6U)) >> 6U);

        if (k == 0U)
        {
            Ifx_Ssw_MTCR(CPU_FCX, nxt_cxi_val);   /* store the new pcxi value to LCX */
        }
        else
        {
            *prvCsa = nxt_cxi_val;
        }

        if (k == (numOfCsa - 3U))
        {
            Ifx_Ssw_MTCR(CPU_LCX, nxt_cxi_val);   /* Last but 2 context save area is pointed in LCX to know if there is CSA depletion */
        }

        prvCsa  = (unsigned int *)nxtCsa;
        nxtCsa += IFX_SSW_CSA_SIZE; /* next CSA */
    }

    *prvCsa = 0U;                   /* Store null pointer in last CSA (= very first time!) */

    Ifx_Ssw_DSYNC();
}

3. 创建任务时分配csa

StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack,
                                     TaskFunction_t pxCode,
                                     void * pvParameters )
{
    uint32_t * pulUpperCSA = NULL;
    uint32_t * pulLowerCSA = NULL;

    /* 16 Address Registers (4 Address registers are global), 16 Data
     * Registers, and 3 System Registers.
     *
     * There are 3 registers that track the CSAs.
     *  FCX points to the head of globally free set of CSAs.
     *  PCX for the task needs to point to Lower->Upper->NULL arrangement.
     *  LCX points to the last free CSA so that corrective action can be taken.
     *
     * Need two CSAs to store the context of a task.
     *  The upper context contains D8-D15, A10-A15, PSW and PCXI->NULL.
     *  The lower context contains D0-D7, A2-A7, A11 and PCXI->UpperContext.
     *  The pxCurrentTCB->pxTopOfStack points to the Lower Context RSLCX matching the initial BISR.
     *  The Lower Context points to the Upper Context ready for the return from the interrupt handler.
     *
     * The Real stack pointer for the task is stored in the A10 which is restored
     * with the upper context. */

    /* Have to disable interrupts here because the CSAs are going to be
     * manipulated. */
    portENTER_CRITICAL();
    {
        /* DSync to ensure that buffering is not a problem. */
        _dsync();

        /* Consume two free CSAs. */
        pulLowerCSA = portCSA_TO_ADDRESS( __MFCR( $FCX ) );

        if( NULL != pulLowerCSA )
        {
            /* The Lower Links to the Upper. */
            pulUpperCSA = portCSA_TO_ADDRESS( pulLowerCSA[ 0 ] );
        }

        /* Check that we have successfully reserved two CSAs. */
        if( ( NULL != pulLowerCSA ) && ( NULL != pulUpperCSA ) )
        {
            /* Remove the two consumed CSAs from the free CSA list. */
            _disable();
            _dsync();
            _mtcr( $FCX, pulUpperCSA[ 0 ] );
            _isync();
            _enable();
        }
        else
        {
            /* Simply trigger a context list depletion trap. */
            _svlcx();
        }
    }
    portEXIT_CRITICAL();

    /* Clear the upper CSA. */
    memset( pulUpperCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) );

    /* Upper Context. */
    pulUpperCSA[ 2 ] = ( uint32_t ) pxTopOfStack;      /* A10; Stack Return aka Stack Pointer */
    pulUpperCSA[ 1 ] = portSYSTEM_PROGRAM_STATUS_WORD; /* PSW  */

    /* Clear the lower CSA. */
    memset( pulLowerCSA, 0, portNUM_WORDS_IN_CSA * sizeof( uint32_t ) );

    /* Lower Context. */
    pulLowerCSA[ 8 ] = ( uint32_t ) pvParameters; /* A4;  Address Type Parameter Register */
    pulLowerCSA[ 1 ] = ( uint32_t ) pxCode;       /* A11; Return Address aka RA */

    /* PCXI pointing to the Upper context. */
    pulLowerCSA[ 0 ] = ( portINITIAL_PCXI_UPPER_CONTEXT_WORD | ( uint32_t ) portADDRESS_TO_CSA( pulUpperCSA ) );

    /* Save the link to the CSA in the top of stack. */
    pxTopOfStack = ( uint32_t * ) portADDRESS_TO_CSA( pulLowerCSA );

    /* DSync to ensure that buffering is not a problem. */
    _dsync();

    return pxTopOfStack;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1669761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS小知识----qDebug打印中文时乱码

问题&#xff1a;vs在打印中文时乱码 分析解决&#xff1a;编码问题&#xff0c;改为UTF-8试试

2024最新独立版校园跑腿校园社区小程序源码+附教程 适合跑腿,外卖,表白,二手,快递等校园服务

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 后台php&#xff0c;前端uniapp可以二次开 2024最新独立版校园跑腿校园社区小程序源码附教程 测试环境&#xff1a;NginxPHP7.2MySQL5.6 多校版本&#xff0c;多模块&#xff0c;适…

银河麒麟服务器sshd启动失败,报错(code=exited, status=255/EXCEPTION)

服务器版本&#xff0c;银河麒麟高级服务器操作系统V10-SP3 查看sshd服务状态systemctl status sshd&#xff0c;报错(codeexited, status255/EXCEPTION) 查看日志journalctl -xe&#xff0c;没有得到太多有用信息。 尝试卸载ssh服务&#xff0c;并重装&#xff1a; yum r…

螺杆式冷水机的回油问题

螺杆式冷水机出现冷冻油回油不畅是非常让人头痛的事情&#xff0c;一般来说&#xff0c;螺杆式冷水机回油不畅的原因主要是因为在运行过程中&#xff0c;出现冷冻油与制冷剂的气体混合物现象。具体是&#xff0c;在制冷系统的运行中&#xff0c;遇到制冷剂与冷冻机润滑油互溶会…

Kubernetes-容器的生命周期(init容器、健康检查探针、钩子)

目录 一、概述 二、init容器 1.概述 2.init容器作用 3.InitC容器示例 三、容器探针 1.概述 2.探针类型 3.readinessProbe-就绪检测示例 4.livenessProbe-存活检测示例 5.livenessProbe-tcp--检测端口模板 四、钩子 1.概述 2.yaml模板 3.示例 一、概述 1.当一个p…

GO+树莓派+E53_IA1智慧农业模块

简介 之前手头上有小熊派的开发板&#xff0c; 有一个E53_IA1模块&#xff0c; 刚好用到树莓派上&#xff0c; 使用GO进行控制&#xff0c;实现智慧农业模块功能。 模块介绍 模块电路介绍 按硬件分成五块&#xff0c; 其中四块在本次用上了&#xff0c; 分别是 1. 补光模块&…

C语言 | Leetcode C语言题解之第80题删除有序数组中的重复项II

题目&#xff1a; 题解&#xff1a; int removeDuplicates(int* nums, int numsSize) {if (numsSize < 2) {return numsSize;}int slow 2, fast 2;while (fast < numsSize) {if (nums[slow - 2] ! nums[fast]) {nums[slow] nums[fast];slow;}fast;}return slow; }

如何利用代理IP高效采集全球热点,赋能短视频创作?

如何利用代理IP高效采集全球热点&#xff0c;赋能短视频创作&#xff1f; 一、摘要二、代理IP1. 什么是代理IP&#xff1f;2. 代理IP的分类3. 代理的重要性 三、如何选择可靠的代理IP服务商&#xff1f;四、IPIDEA代理IP简介1.IPIDEA简介2.IPIDEA的优势 五、获取代理IP1. 注册平…

【数据结构】折半查找/二分查找 查找判定树+效率分析+完整代码

2.2 折半查找 算法思想 定义&#xff1a; 折半查找&#xff0c;又称二分查找&#xff0c;仅用于有序的顺序表。 实现思路&#xff1a; 1.设置low和high指针&#xff0c;分别在序列首尾&#xff1b; 2.取中间位置mid(lowhigh)/2&#xff1b; 3.若mid所指元素大&#xff0c;则去…

乡村振兴的乡村社会治理创新:创新社会治理模式,提升社会治理能力,构建乡村社会治理新格局,建设和谐美丽乡村

一、引言 乡村振兴是我国现代化进程中的重要战略&#xff0c;而乡村社会治理创新则是乡村振兴的关键环节。随着社会的不断发展和进步&#xff0c;传统的乡村社会治理模式已难以满足当前乡村发展的需要。因此&#xff0c;创新社会治理模式、提升社会治理能力、构建乡村社会治理…

04 贝尔曼最优公式

贝尔曼最优公式 前言1、Motivating examples2、Definition of optimal policy3、Bellman optimality equation(BOE)&#xff1a;Introduction4、 BOE&#xff1a;Maximization on the right-hand side5、BOE&#xff1a;Rewrite as v f(v)6、Contraction mapping theorem7、BO…

最新微信智能电子名片源码 全开源可二开 智能名片系统开发

在数字化日益深入人心的今天&#xff0c;名片已不再是简单的纸质交换工具&#xff0c;而是成为了一个展示个人或企业形象、促进商务交流的重要窗口。分享一款全新的微信智能电子名片系统&#xff0c;源码开源、可二次开发的灵活性&#xff0c;更在功能上进行了全面升级和优化&a…

MySQL软件安装基于压缩包

打开mysql官网网址 MySQL :: Download MySQL Community Server 本次针对版本8的安装包方式进行安装&#xff0c;下载成功后接下来对MySQL进行安装 下载后有一个以zip后缀结尾的压缩包文件 对于安装包方式安装&#xff0c;比起可视化安装省去了许多安装步骤&#xff0c;这里直接…

数据结构的二叉树(c语言版)

一.二叉树的概念 1.二叉树的基本概念 二叉树是一种常见的树状数据结构&#xff0c;它由若干个节点组成&#xff0c;这些节点通过边连接起来。每个节点最多可以有两个子节点&#xff0c;分别称为左子节点和右子节点。 二叉树的特点是每个节点最多有两个子节点&#xff0c;而且…

如何根据列值选择DataFrame中的行?

在Python的数据分析库Pandas中&#xff0c;DataFrame是一种非常强大的数据结构&#xff0c;用于存储和操作表格数据。有时&#xff0c;我们可能需要根据某些列的特定值选择DataFrame中的行。本文将介绍如何使用Pandas进行此类操作&#xff0c;并提供一些实用的示例。 基本原理…

商场学习之微服务

前言 寒假前在新电脑上配置了java环境&#xff0c;maven仓库&#xff0c;node,js&#xff0c;navicat&#xff0c;MySQL&#xff0c;linux&#xff0c;vmware等环境&#xff0c;创建了6个mysql数据库&#xff0c;77张表。 如此多的表&#xff0c;字段&#xff0c;去手写基础…

常用网口操作

目录 网卡闪烁识别 查看光口或者电口 电口查看链接 如何去掉ip地址 网卡闪烁识别 装好系统后&#xff0c;不知道哪个名称对应哪个网卡&#xff0c;可以执行下面的命令。此时物理网卡会一闪一闪&#xff0c;按住ctrc&#xff0c;停止闪烁。这样就不担心找错网卡啦。也不用一…

【计算机网络篇】数据链路层(8)共享式以太网的退避算法和信道利用率

文章目录 &#x1f6f8;共享式以太网的退避算法&#x1f95a;截断二进制指数算法 &#x1f354;共享式以太网的信道利用率 &#x1f6f8;共享式以太网的退避算法 在使用CSMA/CD协议的共享总线以太网中&#xff0c;正在发送帧的站点一边发送帧一边检测碰撞&#xff0c;当检测到…

宝塔面板怎么解决nginx跨域问题

1.找到宝塔的nginx配置文件 宝塔有一点不同&#xff0c;nginx配置文件不在nginx的安装目录中&#xff0c;应当去/www/server/panel/vhost/nginx找到 2.添加你要跨域的地址 location /api {proxy_pass http://localhost:8080;proxy_set_header Host $host;proxy_set_header X-…

故障电弧产生的原因以及相关设备介绍-安科瑞 蒋静

1故障电弧的危害 故障电弧是指由于电气线路或设备中绝缘老化破损、电气连接松动、空气潮湿、电压电流急剧升高等原因引起空气击穿所导致的气体游离放电现象。故障电弧发生时&#xff0c;其中心温度可高达3000 ℃左右&#xff0c;并伴随有金属喷溅物&#xff0c;足以引燃任何可…