Skip to content

Commit 3998669

Browse files
committed
util: Add io32_memcpy, a memcpy that copies one word at a time
Implement memcpy32, a version of memcpy that only performs 32 bit word-wise copying. Based on Pete Dietl's and the mcan implementation. Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
1 parent 9a7ed58 commit 3998669

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

include/zephyr/sys/util.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,26 @@ char *utf8_trunc(char *utf8_str);
498498
*/
499499
char *utf8_lcpy(char *dst, const char *src, size_t n);
500500

501+
/**
502+
* @brief Copy src to dest word-wise
503+
*
504+
* This function copies src to dest 32 bits at a time.
505+
* If one calls this function without src and dst being aligned
506+
* on a 4-byte boundary or if n is not a multiple of 4, it will
507+
* do nothing and return NULL.
508+
*
509+
* NOTE: This function uses __ASSERT to enforce the requirements
510+
* of each parameter given below.
511+
*
512+
* @param dest Destination address (must be aligned to a 4-byte boundary)
513+
* @param src Source address (must be aligned to a 4-byte boundary)
514+
* @param n number of bytes to copy (must be a multiple of 4)
515+
*
516+
* @return destination pointer or NULL on error
517+
*/
518+
volatile void *
519+
io32_memcpy(volatile void * dest, const volatile void * src, size_t n);
520+
501521
#ifdef __cplusplus
502522
}
503523
#endif

lib/os/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ zephyr_sources_ifdef(CONFIG_SYS_MEM_BLOCKS mem_blocks.c)
6464

6565
zephyr_sources_ifdef(CONFIG_WINSTREAM winstream.c)
6666

67+
zephyr_sources_ifdef(CONFIG_IO32_MEM io32_mem.c)
68+
6769
zephyr_library_include_directories(
6870
${ZEPHYR_BASE}/kernel/include
6971
${ZEPHYR_BASE}/arch/${ARCH}/include

lib/os/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ config UTF8
172172
Enable the utf8 API. The API implements functions to specifically
173173
handle UTF-8 encoded strings.
174174

175+
config IO32_MEM
176+
bool "io32_memcpy()"
177+
help
178+
Enable io32_memcpy(). This function is useful when word-wise
179+
copying is required, for example when copying from or to a
180+
memory-mapped peripheral. May be expanded with memset and
181+
similar in the future.
182+
175183
rsource "Kconfig.cbprintf"
176184

177185
rsource "Kconfig.heap"

lib/os/io32_mem.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2021 Pete Dietl
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdint.h>
8+
#include <zephyr/sys/util.h>
9+
#include <zephyr/sys/__assert.h>
10+
11+
#define IS_ALIGNED(X) (!((uintptr_t)X & (sizeof(uint32_t) - 1)))
12+
13+
volatile void *
14+
io32_memcpy(volatile void * dst0, const volatile void * src0, size_t len)
15+
{
16+
__ASSERT(len % 4 == 0, "len must be a multiple of 4!");
17+
18+
volatile uint32_t *dst = dst0;
19+
const volatile uint32_t *src = src0;
20+
21+
__ASSERT(IS_ALIGNED(dst), "dst0 must be aligned to a multiple of 4!");
22+
__ASSERT(IS_ALIGNED(src), "src0 must be aligned to a multiple of 4!");
23+
24+
if (!((len % 4 == 0) && IS_ALIGNED(src) && IS_ALIGNED(dst))) {
25+
return NULL;
26+
}
27+
28+
len /= sizeof(uint32_t);
29+
30+
while (len--) {
31+
*dst = *src;
32+
++dst;
33+
++src;
34+
}
35+
36+
return dst0;
37+
}

0 commit comments

Comments
 (0)