首页 > 评测 > One to Many-多核心编程初探——CY8CKIT-062-BLE评测之二

One to Many-多核心编程初探——CY8CKIT-062-BLE评测之二

  • 作者:
  • 来源:21ic
  • [导读]
  • 任务分配与同步是多核编程的最重要问题
TIM截图20180123164705.jpg

 

图 双核心使用打印串口流程

其中两者的打印代码段均为:

void non_ipc_output(uint32_t cpuid, uint32_t ticks)

{

printf("%08X val:%u\n",

cpuid,

ticks);

}

while(1)

{

non_ipc_output(SCB->CPUID, g_Ticks);

}

运行结果如下:

image4.png

图 双核心使用打印函数运行结果

从结果可以看出来,双核心的打印全部穿插在一起了.看不出来原本的打印内容.发生这样的情况显然不是想要的结果.分析出现问题的根源在于:当前系统仅有的资源被多个核心使用而发生的争夺.

借鉴多进程编程的经验,可以得知解决这一问题的关键在于当某一核心使用该资源时,另外核心必须等待或者直接放弃.一般的做法是设定一定的等待时间,如果过了时间依旧获取不到该资源则进行超时退出等待.于是我们将上文的打印函数进行修改:

void ipc_output(uint32_t cpuid, uint32_t ticks)

{

uint32_t timeout;

uint32_t rtnVal;

// Cy_GPIO_Set(PIN_WRITING);

/* timeout wait to set semaphore */

for (timeout = 0ul; timeout < MY_TIMEOUT; timeout++)

{

rtnVal = (uint32_t)Cy_IPC_Sema_Set(MY_SEMANUM, false);

/* exit the timeout wait if semaphore successfully set or error */

if ((rtnVal == (uint32_t)CY_IPC_SEMA_SUCCESS) || IsSemaError(rtnVal))

{

break;

}

CyDelayUs(1);

}

if (timeout >= MY_TIMEOUT)

{

//Timeout

}

if (rtnVal == CY_IPC_SEMA_SUCCESS)

{

printf("%08X val:%u\n",

cpuid,

ticks);

/* timeout wait to clear semaphore */

for (timeout = 0ul; timeout < MY_TIMEOUT; timeout++)

{

rtnVal = (uint32_t)Cy_IPC_Sema_Clear(MY_SEMANUM, false);

/* exit the timeout wait if semaphore successfully cleared or error */

if ((rtnVal == (uint32_t)CY_IPC_SEMA_SUCCESS) || IsSemaError(rtnVal))

{

break;

}

CyDelayUs(1);

}

if (timeout >= MY_TIMEOUT)

{

//Timeout

}

}

}

再次进行运行,结果如下:

image5.png

图 进行资源保护之后的共享打印结果

因为需要保护的资源要等到某一核心使用完毕之后才能被其他核心使用,这个过程不能被打断,所以称之为原子性操作.不管是多线程还是多核心,这个概念都类似.事实上嵌入式系统的程序员对这个概念并不陌生,ISR中与主循环中都需要修改的参数就必须以原子性操作来修改.

image6.png

图 原子性操作示意

PSoC6上的硬件IPC特性与PDL中的IPC接口

PSoC6处理器中在硬件上就有对IPC的支持,此外PDL中也有详尽的IPC的驱动代码.

PDL中的IPC驱动可以分为三部分:

驱动API:

最底层的API,事实上用户无需调用这个层的API.

文件:cy_ipc_drv.c, cy_ipc_drv.h

管道API:

用于内核之间建立管道进行较大的数据量传输.

文件:cy_ipc_pipe.c, cy_ipc_pipe.h

信号旗API:

用于内核之间同步状态,资源共享.上一章节的例子即是使用Semaphore来进行资源共享的.

  • 本文系21ic原创,未经许可禁止转载!

网友评论