Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unaligned access on M0 cores in FAT file system #4649

Closed
LMESTM opened this issue Jun 27, 2017 · 4 comments
Closed

Unaligned access on M0 cores in FAT file system #4649

LMESTM opened this issue Jun 27, 2017 · 4 comments

Comments

@LMESTM
Copy link
Contributor

LMESTM commented Jun 27, 2017

Description

While running SPI SD card tests on STM32 L0 / M0 targets (e.g. NUCLEO_F091RC), the target would freeze and test end up in timeout:

[1498578756.92][CONN][RXD] >>> Running case #2: 'SPI - SD card exists'...
[1498578756.97][CONN][INF] found KV pair in stream: {{__testcase_start;SPI - SD card exists}}, queued...
[1498578796.53][HTST][INF] test suite run finished after 40.16 sec...
[...]
[1498578796.58][HTST][INF] {{result;timeout}}

Command used for test:
mbed test -m NUCLEO_F091RC -t GCC_ARM -n tests-api-spi

###Analysis
Investigations have shown that the platform aborts after a tentative to write 32bits to an unaligned address:

0x08007eb2 in disk_ioctl (pdrv=0 '\000', cmd=2 '\002',
    buff=0x200029a2 <_main_stack+3514>)
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\filesystem\fat\FATFileSystem.cpp:220
220                     *((DWORD*)buff) = size;

(gdb) bt
#0  0x08007eb2 in disk_ioctl (pdrv=0 '\000', cmd=2 '\002',  buff=0x200029a2 <_main_stack+3514>)
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\filesystem\fat\FATFileSystem.cpp:220
#1  0x08005b6e in find_volume (rfs=0x2000292c <_main_stack+3396>,  path=0x20002928 <_main_stack+3392>, wmode=0 '\000')
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\filesystem\fat\ChaN\ff.cpp:2250
#2  0x08006230 in f_mount (fs=0x20002998 <_main_stack+3504>,    path=0x200029d2 <_main_stack+3562> "", opt=1 '\001')
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\filesystem\fat\ChaN\ff.cpp:2451
#3  0x08008074 in FATFileSystem::mount (this=0x20002984 <_main_stack+3484>,    bd=0x200029d8 <_main_stack+3568>, mount=true)
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\filesystem\fat\FATFileSystem.cpp:268
#4  0x08007fb8 in FATFileSystem::mount (this=0x20002984 <_main_stack+3484>,    bd=0x200029d8 <_main_stack+3568>)
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\filesystem\fat\FATFileSystem.cpp:250
#5  0x0800031c in test_card_present () at .\TESTS\API\SPI\SPI.cpp:67
#6  0x0800a910 in utest::v1::Harness::run_next_case ()
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\frameworks\utest\source\utest_harness.cpp:338
#7  0x0800ac42 in utest_us_ticker_run ()
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\frameworks\utest\source\utest_shim.cpp:123
#8  0x0800a1bc in utest::v1::Harness::run (specification=...)
    at C:\Data\Workspace\ci-test-shield\mbed-os\features\frameworks\utest\source\utest_harness.cpp:155
#9  0x080005f2 in main () at .\TESTS\API\SPI\SPI.cpp:165

Proposed way forward

Need to align the struct overall or at least the ssize member ...

$ git diff features/filesystem/fat/ChaN/ff.h
diff --git a/features/filesystem/fat/ChaN/ff.h b/features/filesystem/fat/ChaN/ff.h
index 3653a80..b9cc04c 100644
--- a/features/filesystem/fat/ChaN/ff.h
+++ b/features/filesystem/fat/ChaN/ff.h
@@ -85,7 +85,7 @@ typedef struct {
        WORD    id;                             /* File system mount ID */
        WORD    n_rootdir;              /* Number of root directory entries (FAT12/16) */
 #if _MAX_SS != _MIN_SS
-       WORD    ssize;                  /* Bytes per sector (512, 1024, 2048 or 4096) */
+       WORD    ssize __attribute__ ((aligned (32)));                   /* Bytes per sector (512, 1024, 2048 or 4096) */
 #endif
 #if _FS_REENTRANT
        _SYNC_t sobj;                   /* Identifier of sync object */
@0xc0170
Copy link
Contributor

0xc0170 commented Jun 27, 2017

cc @geky @simonqhughes

@geky
Copy link
Contributor

geky commented Jun 27, 2017

Ah! Good catch! It looks like the issue here is actually an incorrect cast in the fatfs's disk_ioctl function (the porting layer from BlockDevice -> ChanFS).

The disk_ioctl function uses a void* for different argument types, and is incorrectly being interpreted as a 32-bit DWORD variable when ChanFS is expecting a 16-bit WORD.

Pull request up here:
#4652

Let us know if this doesn't fix the issue.

@geky
Copy link
Contributor

geky commented Aug 16, 2017

I think this is fixed now, feel free to reopen if I'm wrong : )

@geky geky closed this as completed Aug 16, 2017
@LMESTM
Copy link
Contributor Author

LMESTM commented Aug 17, 2017

I confirm this has been fixed indeed ! Thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants