Skip to content

The frdm_k64f board resets itself periodically/A possible NXP MPU bug #13482

@tgorochowik

Description

@tgorochowik

Describe the bug
The frdm_k64f board seems to simply reset itself periodically, no error or fault is shown.
It happens more or less often depending on the sample and its configuration.

To Reproduce
I've found, that it is the easiest to reproduce this issue using the samples/net/gptp sample, with NET_BUF_POOL_USAGE and NET_DEBUG_NET_PKT_ALLOC enabled. In such configuration, the board resets itself almost instantly (like every second), here is a sample output:

uart:~$ ***** Booting Zephyr OS v1.14.0-rc1-251-gd079ce05c7 *****
                                                                
                                                                
[00:00:00.007,651] <inf> net_config: Initializing network       
[00:00:00.007,676] <inf> net_config: IPv4 address: 192.0.2.1    
[00:00:00.110,076] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
[00:00:00.110,163] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
uart:~$ ***** Booting Zephyr OS v1.14.0-rc1-251-gd079ce05c7 *****
                                                                
                                                                
[00:00:00.007,651] <inf> net_config: Initializing network       
[00:00:00.007,676] <inf> net_config: IPv4 address: 192.0.2.1    
[00:00:00.110,076] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
[00:00:00.110,163] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
uart:~$ ***** Booting Zephyr OS v1.14.0-rc1-251-gd079ce05c7 *****
                                                                
                                                                
[00:00:00.007,651] <inf> net_config: Initializing network       
[00:00:00.007,676] <inf> net_config: IPv4 address: 192.0.2.1    
[00:00:00.110,076] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
[00:00:00.110,163] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
uart:~$ ***** Booting Zephyr OS v1.14.0-rc1-251-gd079ce05c7 *****
                                                                
                                                                
[00:00:00.007,651] <inf> net_config: Initializing network       
[00:00:00.007,676] <inf> net_config: IPv4 address: 192.0.2.1    
[00:00:00.110,076] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62
[00:00:00.110,163] <inf> net_config: IPv6 address: fe80::204:9fff:fe36:bf62

(...)

It does happen with other configurations/samples too. Just less often. I think that the number of threads plays a significant role too.

Also note, that even though it is a networking sample, the Ethernet cable does not even have to be connected to reproduce this.

Expected behavior
The resets should not be happening.

Environment (please complete the following information):

  • OS: Linux
  • Zephyr SDK
  • Commit SHA: d079ce0

Additional context

I bisected the code, and found, that this PR is when it started: #12817.

Looking at what is different to what was happening earlier, is that the main MPU region mapping is deleted and re-created each time the dynamic regions are to be changed (so when a thread is created or switched) - it seems that earlier, the main MPU mapping for RAM was done just once and left unchanged.

Looking at what actually happens there, I've noticed that there are some spinlocks, but the interrupts are never disabled - shouldn't they be?

I've come with a following fix:

From fc5b87fb2dff32d4348725da1e22fd276acb2f81 Mon Sep 17 00:00:00 2001
From: Tomasz Gorochowik <tgorochowik@antmicro.com>
Date: Mon, 18 Feb 2019 16:08:01 +0100
Subject: [PATCH] arch: arm: mpu: Lock interrupts before re-mapping MPU

This fixes the issue with periodical resets of the frdm_k64f board.

Signed-off-by: Tomasz Gorochowik <tgorochowik@antmicro.com>
---
 arch/arm/core/cortex_m/mpu/arm_core_mpu.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/core/cortex_m/mpu/arm_core_mpu.c b/arch/arm/core/cortex_m/mpu/arm_core_mpu.c
index 6ebedd1948..1e395c855f 100644
--- a/arch/arm/core/cortex_m/mpu/arm_core_mpu.c
+++ b/arch/arm/core/cortex_m/mpu/arm_core_mpu.c
@@ -130,6 +130,7 @@ void _arch_configure_dynamic_mpu_regions(struct k_thread *thread)
 	struct k_mem_partition dynamic_regions[_MAX_DYNAMIC_MPU_REGIONS_NUM];
 
 	u8_t region_num = 0;
+	int key;
 
 #if defined(CONFIG_USERSPACE)
 	/* Memory domain */
@@ -208,9 +209,13 @@ void _arch_configure_dynamic_mpu_regions(struct k_thread *thread)
 	region_num++;
 #endif /* CONFIG_MPU_STACK_GUARD */
 
+	key = irq_lock();
+
 	/* Configure the dynamic MPU regions */
 	arm_core_mpu_configure_dynamic_mpu_regions(dynamic_regions,
 		region_num);
+
+	irq_unlock(key);
 }
 
 #if defined(CONFIG_USERSPACE)
-- 
2.20.1

This seems to fully resolve the issue for me. However I am not sure if that is the correct approach to solving this issue and thus I decided to post it as an issue rather than a PR.

@ioannisg would you mind taking a look at this as the author of the PR I mentioned?

Metadata

Metadata

Assignees

Labels

bugThe issue is a bug, or the PR is fixing a bugplatform: NXPNXPpriority: mediumMedium impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions