这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【S32K3XX】SEMA42 模块使用

共3条 1/1 1 跳转至

【S32K3XX】SEMA42 模块使用

高工
2026-03-10 13:31:51     打赏

【简介】

               S32K3 是一个多核的芯片,在硬件的设计上是存在硬件的锁机制来实现核心之间的互斥访问,对应的 SEMA42 这个IP 继承了硬件的互斥锁锁机制。从以下这张图也可以看出,S32K3 系列芯片多核的MCU芯片都是集成了 SEMA42 这个IP.

image.png

   SEMA42 的驱动配置可以通过S32DS 的RM 模块来配置。

image.png

勾选上SEM后在Sem42 下配置使用的硬件 channel 配置。 

image.png

配置好后更新代码后 SEMA42 相关的驱动代码已经被加入工程中。

image.png

以下是SEMA42 的功能框图,从以下的描述可以知道SEMA42  可以被不同的domain 来持有,对应的通道被lock 状态只有对应的 domain 才可以 unlock,每个核心可以配置DID该部分需要在XRDC中进行配置,对于XDRC的配置可以查看此贴(【S32K3XX】XRDC 功能使用)。

image.png

以下是SEMA42  IP 的驱动接口说明,接口的用法说明还是比较简单的。

image.png

image.png

我们只需要Sema42_Ip_Init,Sema42_Ip_LockGate,Sema42_Ip_UnlockGate 即可以完成核间的互斥访问保护临界资源。

以下是本地 core0(domain id = 0),core1(domain id = 1),对一块共享内存区域进行保护代码。

core0 的测试代码

/* Sema42 init */
Sema42_Ip_Init(SEMA42_INSTANCE0);


while(SEMA42_IP_ERROR == Sema42_Ip_LockGate(SEMA42_INSTANCE0,0,0))
{
vTaskDelay(10);
}

while(RingBuffer_GetDataLength(&pvuart->master_rx_slave_tx))
{
RingBuffer_Read(&pvuart->master_rx_slave_tx,&data,1);
PRINTF("%c",data);
}

if(SEMA42_IP_ERROR == Sema42_Ip_UnlockGate (SEMA42_INSTANCE0,0))
{
PRINTF("Unlock gate failed.\n");
}

core1 的测试代码

while(SEMA42_IP_ERROR == Sema42_Ip_LockGate(SEMA42_INSTANCE0,0,1))
{
//vTaskDelay(10);
}

ret = RingBuffer_Read((RingBuffer *)(&pvuart->master_tx_slave_rx),pdata,1);

if(SEMA42_IP_ERROR == Sema42_Ip_UnlockGate (SEMA42_INSTANCE0,0))
{
PRINTF("Unlock gate failed.\n");
}


验证了SEMA42 的lock/unlock 功能我们继续验证获取channel 的状态信息,我们早CORE1 上lock 住channel2,然后在CORE0上获取channel2 的状态,分别在CORE0/CORE1上添加如下的测试代码来操作 lock/unlock/getlocker。

unsigned int sema42(char argc, char **argv)
{
    if(argc == 3 && strcmp(argv[1],"lock") == 0)
    {
        uint8_t gate = (uint8_t)atoi(argv[2]);
        if(SEMA42_IP_ERROR == Sema42_Ip_LockGate(SEMA42_INSTANCE0,gate,CFG_XRDC_DID))
        {
            PRINTF("Lock gate failed.\n");
        }
        else
        {
            PRINTF("Lock gate success.\n");
        }
    }
    else if(argc == 3 && strcmp(argv[1],"unlock") == 0)
    {
        uint8_t gate = (uint8_t)atoi(argv[2]);
        if(SEMA42_IP_ERROR == Sema42_Ip_UnlockGate (SEMA42_INSTANCE0,gate))
        {
            PRINTF("Unlock gate failed.\n");
        }
        else
        {
            PRINTF("Unlock gate success.\n");
        }
    }
    else if(argc == 3 && strcmp(argv[1],"locker") == 0)
    {
        uint8_t gate = (uint8_t)atoi(argv[2]);
        PRINTF("Gate locker: %d\n", Sema42_Ip_GetGateLocker(SEMA42_INSTANCE0,gate));
    }
    else
    {
        PRINTF("Usage:\n");
        PRINTF("  sema42 lock <gate_index>\n");
        PRINTF("  sema42 unlock <gate_index>\n");
        PRINTF("  sema42 locker <gate_index>\n");
    }
    return 0;
}

本地如下测试:

step1: core1 lock gate2

step2:core0 lock gate2

step3:core0 get locker

运行结果和预期的一致,core0 获取锁失败,查询锁状态为core1 持有。

image.png



           


院士
2026-03-10 14:50:21     打赏
2楼

好简捷哪。


专家
2026-03-12 08:15:28     打赏
3楼

谢谢分享


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]