TriCore: 从RTOS内核的角度看CSA

今天尝试从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.mfbz.cn/a/608778.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode每日一题】 分治 - 交易逆序对的总数(难度⭐⭐⭐)(74)

1. 题目解析 题目链接&#xff1a;LCR 170. 交易逆序对的总数 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 归并排序的基本思路 归并排序将数组从中间分成两部分&#xff0c;在排序的过程中&#xff0c;逆序对的来…

民航电子数据库:在console或服务器登录数据库

目录 前言登录切换数据库 前言 在不使用数据库管理工具的情况下&#xff0c;可以在console或服务器上操作数据库&#xff0c;这时就需要使用相关命令登录到数据库 登录 caeconsole nssl IP地址 端口 数据库名称 用户名 密码 切换数据库 use 数据库名称

springboot+vue+mybatis警情高发智能灯箱+PPT+论文+讲解+售后

时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;警情高发智能灯箱当然不能排除在外。警情高发智能灯箱是在实际应用和软件工程的开发原理之上&#xff0c;运用微信开发者、java语言以及SpringBo…

拦截器添加以及注册

自定义拦截器 自定义一个类 实现 HandlerInterceptor 接口 并重写里面的方法 preHandle、postHandle、afterCompletion preHandle&#xff1a;在执行具体的Controller方法之前调用 postHandle&#xff1a;controller执行完毕之后被调用 afterCompletion&#xff1a;方法需要…

关于FreeRTOS/Nuttx/Zephyr对于用户态程序实现的对比

前言&#xff1a; 现在很多单片机有MPU。比如STM32F4 F7 H7等以ARM CM3 CM4 CM为架构的单片机。那么现在很多RTOS都支持MPU配置&#xff0c;利用MPU实现用户态程序和内核态程序隔离。 从用户产品经理角度出发&#xff0c;作为RTOS的使用者&#xff0c;以一个简单的商业例子来…

区块链 | NFT 水印:Review on Watermarking Techniques(三)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 一个 NFT 的水印认证协议 可以引入第三方实体来实现对交易的认证&#xff0c;即通过使用 R S A \mathsf{RSA} RSA…

喜报|知从科技荣获“2023年度浦东新区创新创业奖”

4月11日&#xff0c;由上海市浦东新区人民政府举办的“2024年浦东新区经济突出贡献企业表彰活动”在上海国际会议中心隆重举行。知从科技凭借过去一年在行业内卓越的技术创新实力及对浦东新区发展作出的杰出贡献&#xff0c;入选创新创业20强企业&#xff0c;荣获“2023年度浦东…

Coze扣子开发指南:用免费API自己创建插件

虽然Coze扣子现在插件商店已经有几百个插件了&#xff0c;但相对于海量人群的众多差异化需求&#xff0c;还是远远不够的。如果插件商店没有合适的插件&#xff0c;其实完成可以自己创建&#xff0c;过程也很简单&#xff0c;不需要编写任何代码。 首先打开个人空间&#xff0…

python:做柱状图

import matplotlib.pyplot as plt # 数据 categories [A, B, C, D] values [23, 45, 56, 78] # 创建柱状图 plt.bar(categories, values) # 添加标题和标签 plt.title(柱状图示例) plt.xlabel(类别) plt.ylabel(数值) # 显示图形 plt.show() D:\software\新建文件夹\python\L…

elementui- button按钮自适应大小

<el-button type"primary" class"daochu" click"download">导出</el-button> .daochu {width: calc(100vw * 80 / 1920);height: calc(100vw * 30 / 1920);font-size: calc(100vw * 13 / 1920); } 效果图&#xff1a;

顺序表详解及应用(通讯录的实现)

一.线性表 线性表&#xff1a;n个具有相同特性的的数据元素的有限序列。线性表是一种在实际中广泛应用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表&#xff0c;链表&#xff0c;栈&#xff0c;队列&#xff0c;字符串... 线性表在逻辑上是线性结构&#xff0c;也就…

一、计算机基础(Java零基础一)

&#x1f33b;&#x1f33b;目录 一、&#x1f33b;&#x1f33b;剖析学习Java前的疑问&#x1f33b;&#x1f33b;1.1 零基础学习编程1.2 英语不好能学吗&#xff1f;1.3 理解慢能学好吗&#xff1f;1.4 现在学Java晚吗&#xff1f;1.5 Java 和 Python 还有 Go 的选择1.6 Java…

Rust 使用egui创建一个简单的下载器demo

仓库连接: https://github.com/GaN601/egui-demo-download-util 这是我第一个rust gui demo, 学习rust有挺长时间了, 但是一直没有落实到实践中, 本着对桌面应用的兴趣, 考察了slint、egui两种框架, 最后还是选择了egui. 这篇博客同时包含我当前的一些理解, 但是自身技术有限,…

ESP8266基础资源了解

封装的硬件资源 参考1&#xff0c;参考2 常说的esp8266指的是有一个屏蔽罩盖着的模块&#xff0c;里面包含了esp8266芯片和一个能够存储数据和程序的flash&#xff0c;因为esp8266没有存储功能。 使用arduino常用的nodemcu是包含这个模块并含有电源LDO和串口下载的设计电路如…

WINDOWS下zookeeper突然无法启动但是端口未占用的解决办法(用了WSL)

windows下用着用着时候突然zookeeper启动不了了。netstat查也没有找到端口占用&#xff0c;就是起不来。控制台报错 java.lang.reflect.UndeclaredThrowableException: nullat org.springframework.util.ReflectionUtils.rethrowRuntimeException(ReflectionUtils.java:147) ~…

铁山靠之数学建模 - Matlab入门

Matlab基础 1. Matlab界面与基本操作1.1 matlab帮助系统1.2 matlab命令1.3 matlab功能符号1.4 matlab的数据类型1.5 函数计算1.6 matlab向量1.7 matlab多项式1.8 M文件1.9 函数文件1.10 matlab的程序结构1.11 echo、warning和error函数1.12 交互输入1.13 程序调试1.14 设置断点…

Centos固定静态ip地址

这里我用的是Vmware虚拟机搭建的三台机器 进入 cd /etc/sysconfig/network-scripts然后使用 ip addr命令&#xff0c;查看自己虚拟机的以太网地址。 我这里是ens33 上面的第一个选项是本地环回地址&#xff0c;不用管它 然后查看刚刚进入的network-scripts目录下的文件 找到…

Mybatis框架笔记:基础信息

1.Mybatis介绍 MyBatis本是apache的一个开源项目iBatis&#xff0c;2010年这个项目由apache software foundation迁移到了google code&#xff0c;并且改名为MyBatis。2013年11月迁移到Github。 iBATIS一词来源于“internet”和“abatis”的组合&#xff0c;是一个基于Java的持…

AI赋能EasyCVR视频汇聚/视频监控平台加快医院安防体系数字化转型升级

近来&#xff0c;云南镇雄一医院发生持刀伤人事件持续发酵&#xff0c;目前已造成2人死亡21人受伤。此类事件在医院层出不穷&#xff0c;有的是因为医患纠纷、有的是因为打架斗殴。而且在每日大量流动的人口中&#xff0c;一些不法分子也将罪恶的手伸到了医院&#xff0c;实行扒…

健康知识集锦

页面 页面代码 <% layout(/layouts/default.html, {title: 健康知识管理, libs: [dataGrid]}){ %> <div class"main-content"><div class"box box-main"><div class"box-header"><div class"box-title"&g…
最新文章