memcpy crashes when writing to non-cached memory on ARM M7

Bug #1857469 reported by David Crocker
16
This bug affects 3 people
Affects Status Importance Assigned to Milestone
GNU Arm Embedded Toolchain
Won't Fix
Undecided
Unassigned

Bug Description

The version of memcpy in standard newlib (not the one in newlib-nano) crashes when it is used to write to memory that has been tagged as non-cacheable in the MPU. This is because non-cacheable memory only supports aligned accesses. In embedded systems using the ARM Cortex M7 processor, sections of non-cacheable memory are often required, because the write-back cache of the ARM M7 plays havoc with DMA. Although memcpy attempts to do aligned accesses, if the number of bytes to be copied is one less than a multiple of 4 then memcpy uses a 16-bit transfer to copy the last 2 bytes.

Workaround 1: use newlib-nano instead. Unfortunately, newlib-nano as provided is not compatible with programs that use exception handling.

Workaround 2: copy the source code for memcpy from newlib source into your project, and compile it with option -fno-unaligned-access (like the rest of the project that uses non-cached memory). As a precaution I did the same for memset, memmove and memcmp too.

Suggested fix: as it is likely that programs targeting the ARM Cortex M7 will need to use areas of non-cached memory, either all of newlib or just these memory access functions should be compiled with option -fno-unaligned-access when targeting the ARM Cortex M7.

Tags: memcpy
Revision history for this message
stewo (wolfer-y) wrote : [Autoreply] [Bug 1857469] [NEW] memcpy crashes when writing to non-cached memory on ARM M7
Download full text (3.9 KiB)

Ich bin bis 08.01. nicht im Haus und kann Ihre Nachricht daher leider nicht bearbeiten. In dringenden Fällen wenden Sie sich bitte an <email address hidden> bzw. für technische Fragen an <email address hidden>.

I am out of office until January 8th and won't be able to read your message. In urgent cases, please refer to <email address hidden> or for technical questions to <email address hidden>.

Mit freundlichen Grüßen / Best regards

Steffen Wolfer

--
Dipl.-Inform. Steffen Wolfer
Software Engineer Embedded Systems

WEISS ROBOTICS GmbH & Co. KG
Karl-Heinrich-Käferle-Str. 8
D-71640 Ludwigsburg, Germany

Phone: +49 7141 94702-22
Fax: +49 7141 94702-99
http://www.weiss-robotics.com

Sitz der Gesellschaft: Ludwigsburg
Registergericht Stuttgart, HRA725006

Pers. haftende Gesellschafterin:
Weiss Robotics Verwaltungs-GmbH, Sitz Ludwigsburg
Registergericht Stuttgart, HRB73310
Geschäftsführer: Dr. Karsten Weiß

Public bug reported:

The version of memcpy in standard newlib (not the one in newlib-nano)
crashes when it is used to write to memory that has been tagged as non-
cacheable in the MPU. This is because non-cacheable memory only supports
aligned accesses. In embedded systems using the ARM Cortex M7 processor,
sections of non-cacheable memory are often required, because the write-
back cache of the ARM M7 plays havoc with DMA. Although memcpy attempts
to do aligned accesses, if the number of bytes to be copied is one less
than a multiple of 4 then memcpy uses a 16-bit transfer to copy the last
2 bytes.

Workaround 1: use newlib-nano instead. Unfortunately, newlib-nano as
provided is not compatible with programs that use exception handling.

Workaround 2: copy the source code for memcpy from newlib source into
your project, and compile it with option -fno-unaligned-access (like the
rest of the project that uses non-cached memory). As a precaution I did
the same for memset, memmove and memcmp too.

Suggested fix: as it is likely that programs targeting the ARM Cortex M7
will need to use areas of non-cached memory, either all of newlib or
just these memory access functions should be compiled with option -fno-
unaligned-access when targeting the ARM Cortex M7.

** Affects: gcc-arm-embedded
     Importance: Undecided
         Status: New

** Tags: memcpy

--
You received this bug notification because you are subscribed to GNU Arm
Embedded Toolchain.
Matching subscriptions: Älles
https://bugs.launchpad.net/bugs/1857469

Title:
  memcpy crashes when writing to non-cached memory on ARM M7

Status in GNU Arm Embedded Toolchain:
  New

Bug description:
  The version of memcpy in standard newlib (not the one in newlib-nano)
  crashes when it is used to write to memory that has been tagged as
  non-cacheable in the MPU. This is because non-cacheable memory only
  supports aligned accesses. In embedded systems using the ARM Cortex M7
  processor, sections of non-cacheable memory are often required,
  because the write-back cache of the ARM M7 plays havoc with DMA.
  Although memcpy attempts to do aligned accesses, if the number of
  bytes to be copied is one less than a multiple of 4 then memcpy uses a
  16-bit transfer to copy the la...

Read more...

Revision history for this message
Darius Babrauskas (darius1) wrote :

Hi,
I am working with ARM Cortex M7 too.
My notes:
>>Workaround 1: use newlib-nano instead. Unfortunately, newlib-nano as provided is not compatible with programs that use exception handling.

if use newlib-nano and non-cacheable memory and optimization -Og, then your project need compile with option -fno-unaligned-access, because memcpy(ps,pd,4) after optimization became *(int32_t*)ps = *(int32_t*)pd; So if address not aligned we got alignment exception. Same with strcpy ...

>> Suggested fix: as it is likely that programs targeting the ARM Cortex M7
will need to use areas of non-cached memory, either all of newlib or
just these memory access functions should be compiled with option -fno-
unaligned-access when targeting the ARM Cortex M7.

Yes I agree. My opinion, need version of newlib-nano compiled with -fno-
unaligned-access.

Revision history for this message
Joey Ye (jinyun-ye) wrote :

There are workarounds and we have no plan to release unaligned library.

Changed in gcc-arm-embedded:
status: New → Won't Fix
Revision history for this message
Jonathan (vervaeke-jonathan) wrote :

Would there be any documentation available on how to cross compile newlib for ARM Cortex M7 with this flag enabled?

Revision history for this message
David Osborne (davidoz) wrote :

Hi All, I'm using a Cortex M7 with external NOR Flash and external SDRAM which require aligned memory access. Consequently, I have the same problem as the OP.

I should caution everyone that the workarounds offered do not fix all scenarios. There are other inbuilt copy routines that have the same problem as the memcpy.

Workaround 1: Use newlib-nano. It's true that library's memcpy uses a byte wise copy, but there are other library code that uses integer copy. e.g.

class ArrayTest
{
public:
    ArrayTest() {}
    ~ArrayTest()
    {
    }

    void MakeEqual()
    {
        mArrayA = mArrayB; // will cause a hardfault if array access requires aligned access.
    }

private:
    std::array<bool, 10> mArrayA = { 0 }; // I've also seen some constructors hit a hardfault
    std::array<bool, 10> mArrayB = { 0 };
};

Workaround 2: Implement your own memcpy, memset, strcpy, etc. This workaround won't work 100% for the same reason Workaround 1 doesn't work for 100%. In the above example 'mArrayA = mArrayB;' doesn't call memcpy. It uses its own copy code that can't be overridden. Who knows what other STL classes have their own copy operator.

My solution was to setup the MPU to cover the external Flash and SDRAM. I made sure the TEX level was set to 1. This prevented the hardfault from occurring without any change to the code. Unfortunately my knowledge of the MPU is very limited, so I can't be sure if this is a working solution. I'd be grateful for any opinions on this.

Cheers
David

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.