Skip to content

Conversation

@pdietl
Copy link
Contributor

@pdietl pdietl commented Dec 16, 2021

No description provided.

@pdietl
Copy link
Contributor Author

pdietl commented Dec 16, 2021

I need @alexanderwachter I need some help testing this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scary gcc attribute. But I assume all supported toolchains are in CI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this is scary, but there is no other way to get around strict aliasing that I know of :(

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add ZRESTRICT to match memcpy() in lib/libc/minimal/include/string.h?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scary gcc attribute. But I assume all supported toolchains are in CI.

actually they are not.

Only the Zephyr SDK and clang is in CI, but none of the other commercial toolchains.

Other toolchains are gcc or clang based, so if this works with those two, I expect other toolchain should work.
@pdietl can you ensure that this will be tested by CI for minimum Zephyr SDK and clang.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strange, I thought restrict was only useful if the same memory address was read multiple times.

But we don't read the same address multiple times in this memcpy.

Did you see any changes to the generated machine code with and without the restrict keyword?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regular memcpy uses restrict in its parameters, so I did the same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it anyway

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Zephyr, you can use ZRESTRICT.

Copy link
Contributor

@SebastianBoe SebastianBoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting a Kconfig so we don't build this for the vast majority of builds.

@pdietl
Copy link
Contributor Author

pdietl commented Dec 17, 2021

@henrikbrixandersen huh that's an interesting error. Plz help :)

@pdietl
Copy link
Contributor Author

pdietl commented Dec 17, 2021

Hmm the PDF documentation gen seems to work well
image
Bu the HTML fails?

@alexanderwachter
Copy link
Member

alexanderwachter commented Dec 18, 2021

@pdietl works on the nucleo_g474re
Edit: sorry. did not switch the branch...

START - test_send_and_forget
E: ***** BUS FAULT *****
E: Imprecise data bus error
E: r0/a1: 0x00000000 r1/a2: 0x15540000 r2/a3: 0x00000008
E: r3/a4: 0x503cb4f3 r12/ip: 0x00000001 r14/lr: 0x08003955
E: xpsr: 0x81000000
E: Faulting instruction address (r15/pc): 0x08001cbc
E: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
E: Current thread: 0x200001a0 (test_send_and_forget)
E: Halting system

addr2line -a 0x08001cbc -e build/zephyr/zephyr.elf
0x08001cbc
zephyrproject/zephyr/lib/os/memcpy32.c:39 (discriminator 1)

Copy link
Member

@alexanderwachter alexanderwachter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not work on HW

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while (len >= 0) {
while (len > 0) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size_t cannot be negative.

@tejlmand
Copy link
Contributor

@SebastianBoe Should I make mcan depend on memcpy32 or have mcan select memcpy32 ?

Use select, please.

Are you sure ?
Are we certain that all toolchains support this:
https://github.com/zephyrproject-rtos/zephyr/blob/310e736211c8570469ad42a9b942c720072982c9/lib/os/memcpy32.c#L18

If not, then we could risk ending in a situation where the MEMCPY32 must have a depends on <some toolchain> which again may risk a:

warning: MEMCPY32 (defined at ...) has direct dependencies <SOME_TOOLCHAIN> with value n, but is currently being y-selected by the following symbols:
 - CAN_MCAN (defined at ...), with value y .....

error: Aborting due to Kconfig warnings

when using a select MEMCPY32 here.

As minimum we should ensure Zephyr SDK and clang is supporting __ma_alias, as the toolchains currently supported er either gcc or clang based.

Copy link
Contributor

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When building tests/drivers/can/canfd/drivers.canfd for nucleo_g474re I get the following errors (warning turned into errors) with twister:

/projects/github/ncs/zephyr/drivers/can/can_mcan.c: In function 'can_mcan_init':
/projects/github/ncs/zephyr/drivers/can/can_mcan.c:389:2: error: converting a packed 'struct can_mcan_msg_sram' pointer (alignment 1) to a 'uint32_t' {aka 'unsigned int'} pointer (alignment 4) may result in an unaligned pointer value [-Werror=address-of-packed-member]
  389 |  for (uint32_t *ptr = (uint32_t *)msg_ram;
      |  ^~~
In file included from /projects/github/ncs/zephyr/drivers/can/can_mcan.c:11:
/projects/github/ncs/zephyr/drivers/can/can_mcan.h:148:8: note: defined here
  148 | struct can_mcan_msg_sram {
      |        ^~~~~~~~~~~~~~~~~
/projects/github/ncs/zephyr/drivers/can/can_mcan.c: In function 'can_mcan_get_message':
/projects/github/ncs/zephyr/drivers/can/can_mcan.c:525:15: error: taking address of packed member of 'struct can_mcan_rx_fifo' may result in an unaligned pointer value [-Werror=address-of-packed-member]
  525 |    for (src = fifo[get_idx].data_32,
      |               ^~~~
/projects/github/ncs/zephyr/drivers/can/can_mcan.c: In function 'can_mcan_send':
/projects/github/ncs/zephyr/drivers/can/can_mcan.c:698:11: error: passing argument 1 of 'memcpy32' discards 'volatile' qualifier from pointer target type [-Werror=discarded-qualifiers]
  698 |  memcpy32(&msg_ram->tx_buffer[put_idx].hdr, &tx_hdr,
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /projects/github/ncs/zephyr/drivers/can/can_mcan.c:7:
/projects/github/ncs/zephyr/include/sys/util.h:385:32: note: expected 'void * restrict' but argument is of type 'volatile struct can_mcan_tx_buffer_hdr *'
  385 | void *memcpy32(void *ZRESTRICT dest, const void *ZRESTRICT src, size_t n);
      |                ~~~~~~~~~~~~~~~~^~~~
/projects/github/ncs/zephyr/drivers/can/can_mcan.c:702:9: error: taking address of packed member of 'struct can_mcan_tx_buffer' may result in an unaligned pointer value [-Werror=address-of-packed-member]
  702 |   dst = msg_ram->tx_buffer[put_idx].data_32,
      |         ^~~~~~~
cc1: all warnings being treated as errors

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scary gcc attribute. But I assume all supported toolchains are in CI.

actually they are not.

Only the Zephyr SDK and clang is in CI, but none of the other commercial toolchains.

Other toolchains are gcc or clang based, so if this works with those two, I expect other toolchain should work.
@pdietl can you ensure that this will be tested by CI for minimum Zephyr SDK and clang.

@alexanderwachter
Copy link
Member

@tejlmand that should be fixed in #41326

@SebastianBoe
Copy link
Contributor

@tejlmand : If a toolchain does not support this then I assume we will get a reasonable error, so I don't see the need for a depends in the Kconfig.

@alexanderwachter
Copy link
Member

alexanderwachter commented Dec 21, 2021

@SebastianBoe @henrikbrixandersen asked for it to speed up compilation time.

Edit:
Was not @henrikbrixandersen.
Think i misread your comment

@tejlmand
Copy link
Contributor

@tejlmand : If a toolchain does not support this then I assume we will get a reasonable error, so I don't see the need for a depends in the Kconfig.

except for twister.
There are plans for getting commercial toolchain support in CI, and twister default runs CMake for dts and Kconfig to determine what should be build, and if a board matches the filter, then the test will build for the board.

So just relying on a sane error message build time could impact twister in bad way.
I'm just trying to minimize the risk of having to go through this at later time.

But first thing I would like to know is whether or not the __may_alias is understood by clang, cause if it is, we may not have an immediate problem.

@tejlmand
Copy link
Contributor

@tejlmand that should be fixed in #41326

Great, so please rebase this PR, so we can continue.

@henrikbrixandersen
Copy link
Member

See #40644 for inspiration.

@henrikbrixandersen
Copy link
Member

@pdietl Do you plan on picking this up again?

@pdietl
Copy link
Contributor Author

pdietl commented Jan 13, 2022

Ok what do I need to do to finish this off @henrikbrixandersen

@pdietl
Copy link
Contributor Author

pdietl commented Jan 13, 2022

Since memcpy32_volatile was added already to can_mcan.c do we still want or need this?

@henrikbrixandersen
Copy link
Member

Since memcpy32_volatile was added already to can_mcan.c do we still want or need this?

It would be nice to have a generic memcpy32() available and replace the driver-local implementation with this.

@SebastianBoe
Copy link
Contributor

Does memcpy32_volatile not use compiler-specific features? If so, re-writing this to use volatile would resolve the main problems with this PR I believe.

@pdietl pdietl force-pushed the add_memcpy32 branch 2 times, most recently from 00b3d63 to 9d9f9bd Compare January 13, 2022 21:48
Implement memcpy32, a version of memcpy that only
performs 32 bit word-wise copying.

Signed-off-by: Pete Dietl <petedietl@gmail.com>
Use memcpy32 for word-wise copying

Fixes zephyrproject-rtos#41074

Signed-off-by: Pete Dietl <petedietl@gmail.com>
@pdietl
Copy link
Contributor Author

pdietl commented Jan 13, 2022

@SebastianBoe I don't think so?

@pdietl
Copy link
Contributor Author

pdietl commented Jan 13, 2022

@henrikbrixandersen Do you want me to change this version of memcpy32 to be volatile?
Regardless I need some help fixing the build failures

Copy link
Contributor

@tejlmand tejlmand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still getting build failures when running twister in tests/drivers/can/canfd/drivers.canfd for nucleo_g474re:

 38%] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/memcpy32.c.obj
/projects/github/ncs/zephyr/lib/os/memcpy32.c: In function 'memcpy32':
/projects/github/ncs/zephyr/lib/os/memcpy32.c:20:14: error: initialization discards 'volatile' qualifier from pointer target type [-Werror=discarded-qualifiers]
   20 |  char *dst = dst0;
      |              ^~~~
/projects/github/ncs/zephyr/lib/os/memcpy32.c:21:20: error: initialization discards 'volatile' qualifier from pointer target type [-Werror=discarded-qualifiers]
   21 |  const char *src = src0;
      |                    ^~~~
cc1: all warnings being treated as errors
make[2]: *** [zephyr/CMakeFiles/zephyr.dir/build.make:398: zephyr/CMakeFiles/zephyr.dir/lib/os/memcpy32.c.obj] Error 1
make[1]: *** [CMakeFiles/Makefile2:2627: zephyr/CMakeFiles/zephyr.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

@pdietl pdietl closed this Feb 8, 2022
@SebastianBoe SebastianBoe mentioned this pull request Oct 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: API Changes to public APIs area: Base OS Base OS Library (lib/os) area: Build System area: CAN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

can_mcan_send sends corrupted CAN frames with a byte-by-byte memcpy implementation

7 participants