简介:
在上一篇我们使用了mailbox 的irq 机制进行核间通信,除了irq mailbox 还自带了个硬件资源的互斥锁特性,访问共享资源时可以先读取mutex状态如果是1代表当前硬件锁是空闲状态可以访问(获取后硬件会自动清零,退出时需要软件设置为1释放锁资源),如果读取的是0说明互斥锁正被持有需等待释放才可使用,对应流程如下。
MCX-N947 的maibox 提供了个核间互斥访问资源的功能,有了这个功能我们就可以对访问共同的共享内存进行保护确保数据的同步正常。MCX-N947的链接脚本可以看出是专门划分了个sh_mem区域可以用于共享资源,我们只要在IAR中定义__use_shmem__ 即可。
在IAR 中添加__use_shmem__ symbol
对应的编译链接选项为 --config_def
在core0 中添加代码对 0x2004C000 进行连续++
static int32_t counter @ 0x2004C000 = 0; unsigned int mutex_test(void) { int i =0x7ffffff; for(;i != 0;i--) { while(MAILBOX_GetMutex(MAILBOX) == 0) ; counter++; MAILBOX_SetMutex(MAILBOX); } rt_thread_mdelay(50000); rt_kprintf("addr %p counter = %d.\r\n",&counter,counter); return 1; } int main(void) { #if defined(__CC_ARM) rt_kprintf("using armcc, version: %d\n", __ARMCC_VERSION); #elif defined(__clang__) rt_kprintf("using armclang, version: %d\n", __ARMCC_VERSION); #elif defined(__ICCARM__) rt_kprintf("using iccarm, version: %d\n", __VER__); #elif defined(__GNUC__) rt_kprintf("using gcc, version: %d.%d\n", __GNUC__, __GNUC_MINOR__); #endif //rt_pin_mode(LEDB_PIN, PIN_MODE_OUTPUT); /* Set GPIO as Output */ rt_pin_mode(BUTTON_PIN, PIN_MODE_INPUT_PULLUP); rt_pin_attach_irq(BUTTON_PIN, PIN_IRQ_MODE_FALLING, sw_pin_cb, RT_NULL); rt_pin_irq_enable(BUTTON_PIN, 1); rt_kprintf("MCXN947 HelloWorld\r\n"); MAILBOX_Init(MAILBOX); NVIC_EnableIRQ(MAILBOX_IRQn); rt_kprintf("send to core1 start test.\n"); MAILBOX_SetValue(MAILBOX,kMAILBOX_CM33_Core1,1); mutex_test(); while (1) { //rt_pin_write(LEDB_PIN, PIN_HIGH); /* Set GPIO output 1 */ rt_thread_mdelay(500); /* Delay 500mS */ //rt_pin_write(LEDB_PIN, PIN_LOW); /* Set GPIO output 0 */ //rt_thread_mdelay(500); /* Delay 500mS */ } }
在core1 中添加如下代码对0x2004C000 进行连续--
static int32_t counter @ 0x2004C000 = 0; unsigned int mutex_test(void) { int i =0x7ffffff; for(;i != 0;i--) { while(MAILBOX_GetMutex(MAILBOX) == 0) ; counter--; MAILBOX_SetMutex(MAILBOX); } return 1; } /*! * @brief Main function */ int main(void) { //uint32_t startupData, i; //mcmgr_status_t status; /* Init board hardware.*/ /* enable clock for GPIO */ CLOCK_EnableClock(kCLOCK_Gpio0); BOARD_InitBootPins(); MAILBOX_Init(MAILBOX); NVIC_EnableIRQ(MAILBOX_IRQn); /* Initialize MCMGR, install generic event handlers */ //(void)MCMGR_Init(); /* Get the startup data */ //do //{ // status = MCMGR_GetStartupData(&startupData); //} while (status != kStatus_MCMGR_Success); /* Make a noticable delay after the reset */ /* Use startup parameter from the master core... */ //for (i = 0; i < startupData; i++) //{ // SDK_DelayAtLeastUs(1000000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); //} /* Configure LED */ LED_INIT(); for (;;) { //SDK_DelayAtLeastUs(500000U, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); //LED_TOGGLE(); if(flag) { mutex_test(); flag = 0; } } }
测试代码下载到板子中运行core0 打印的结果为0 说明互斥访问保护有效
debug 查看core1中对应结果也是0
将上述的互斥锁代码去除在运行cor0 打印结果部位0,也从侧面验证了核间mutex 同步功能是有效的。