Removing SPIBlockDevice module as present in spiflash-driver repository.

pull/7774/head
Simon D Hughes 2017-03-28 17:14:58 +01:00
parent c7dba87363
commit e2fc4fcc44
4 changed files with 11 additions and 990 deletions

455
README.md
View File

@ -262,7 +262,7 @@ is described in more detail in the [Testing with an SDCard on Target XYZ](#testi
Next, build the example application:
simhug01@E107851:/d/demo_area/sd_ex1$ mbed compile -m K64F -t GCC_ARM 2>&1 | tee build_log.txt
simhug01@E107851:/d/demo_area/sd_ex1$ mbed compile -m K64F -t GCC_ARM
#### WARNING: "mbed new ." command and possible mbed-os sd-driver versioning incompatibilities
@ -617,7 +617,7 @@ and is discussed in the [Testing with an SDCard on Target XYZ](#testing-with-an-
Build the test cases for the K64F target using the following command:
simhug01@E107851:/d/demo_area/ex_app1$ mbed -v test --compile -t GCC_ARM -m K64F --app-config mbed_app.json 2>&1 | tee build_tests_gcc_20161219_1007.txt
simhug01@E107851:/d/demo_area/ex_app1$ mbed -v test --compile -t GCC_ARM -m K64F --app-config mbed_app.json
<trace removed>
simhug01@E107851:/d/demo_area/ex_app1$
@ -696,11 +696,11 @@ The names of the tests can be listed using:
For example, to run the basic test use:
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-basic 2>&1 | tee run_tests_basic.txt
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-basic
To run the fopen test use:
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-fopen 2>&1 | tee run_tests_fopen.txt
simhug01@E107851:/d/demo_area/ex_app1$ mbedgt -VS --test-by-names=sd-driver-features-tests-filesystem-fopen
On a successful run, results similar to the following will be shown:
@ -823,449 +823,16 @@ Basic errno reporting is supported, tested and known to be working.
The following are related mbed storage projects and useful resources:
- The [mbed-os repository](https://github.com/ARMmbed/mbed-os). This is the main mbed OS repository.
- The [mbed-os-example-fat-filesystem repository](https://github.com/ARMmbed/mbed-os-example-fat-filesystem).
- The [mbed-os](https://github.com/ARMmbed/mbed-os) main repository.
- The [mbed-os-example-fat-filesystem](https://github.com/ARMmbed/mbed-os-example-fat-filesystem) repository.
This is an example project for the mbed OS FAT filesystem.
- The [spiflash-driver repository](https://github.com/armmbed/spiflash-driver)
- The [i2ceeprom-driver repository](https://github.com/ARMmbed/i2ceeprom-driver.git)
- The [ci-test-shield repository](https://github.com/ARMmbed/ci-test-shield). This is the project describing
- The [spiflash-driver](https://github.com/armmbed/spiflash-driver) repository.
- The [i2ceeprom-driver](https://github.com/ARMmbed/i2ceeprom-driver.git) repository.
- The [ci-test-shield](https://github.com/ARMmbed/ci-test-shield) repository. This is the project describing
the mbed-os Continuous Integration test shield, together with standard tests.
- The [mbed-HDK](https://github.com/ARMmbed/mbed-HDK) repository containing Hardware Development Kit resources
including the schematics for the CI test shield.
- [POSIX File Interface ISO/IEC 9899:TC2 Documentation](http://www.eng.utah.edu/~cs5785/slides-f10/n1124.pdf).
- [FATFS: Generic FAT File System Module used in mbed OS](http://elm-chan.org/fsw/ff/00index_e.html)
# Appendix 1: Getting Started with SPIFlash-Driver Example
## Overview
This example describes how to build and run the spiflash-driver SPIFBlockDevice examples to
read and write data to a SPI NOR flash part connected to a K64F.
Hardware required:
- K64F.
- CI test shield.
- SPI NOR Flash Device wired to Arduino header pins e.g. the Macronix MX25R2035F. The datasheet is available
from the [Macronix website](http://www.macronix.com/).
- Micro USB cable.
Software required:
- mbed CLI (with all other dependencies installed).
- ARMCC / GCC_ARM / IAR compiler.
- mbed greentea.
- git account.
Github repos to use:
- The [mbed OS repository](https://github.com/armmbed/mbed-os)
- The [SPI Flash Driver repository](https://github.com/armmbed/spiflash-driver)
## Simple SPIFBlockDevice Example
This section describes how to create an application project combining the
mbed-os and spiflash-driver repositories into a single project.
In summary the following steps will be covered in this section:
- A top level application project directory is created. The directory name is ex_app2.
- In the ex_app2 directory, the mbed-os repository is cloned.
- In the ex_app2 directory at the same level as the mbed-os directory, the spiflash-driver repository is cloned.
First create the top level application directory ex_app2 and move into it:
simhug01@E107851:/d/demo_area$ mkdir ex_app2
simhug01@E107851:/d/demo_area$ pushd ex_app2
Next, get a clone of public mbed OS repository in the following way:
simhug01@E107851:/d/demo_area/ex_app2$ git clone git@github.com:/armmbed/mbed-os
<trace removed>
simhug01@E107851:/d/demo_area/ex_app2$
Next, get a clone of the spiflash-driver repository:
simhug01@E107851:/d/demo_area/ex_app2$ git clone git@github.com:/armmbed/spiflash-driver
<trace removed>
simhug01@E107851:/d/demo_area/ex_app2$
In the top level directory create the example2.cpp:
simhug01@E107851:/d/demo_area/ex_app2$ touch example2.cpp
Copy the [spiflash-driver example code](https://github.com/armmbed/spiflash-driver)
and paste into example2.cpp (reproduced here for convenience and corrected to build for
GCC_ARM):
// Here's an example using the MX25R SPI flash device on the K82F
#include "mbed.h"
#include "SPIFBlockDevice.h"
/* This is the original configuration of the SPI Flash Driver
* pins for Freescale K82F development board. We're not using
* this as we're using the CI Test Shield
*/
// Create flash device on SPI bus with PTE5 as chip select
//SPIFBlockDevice spif(PTE2, PTE4, PTE1, PTE5);
/* This configuration of the SPI Flash Driver pins is for
* the Freescale K64F connecting the SPI pins on the
* Arduino header to the SPI NOR part.
*/
SPIFBlockDevice spif(D11, D12, D13, D10);
int main() {
printf("spif test\n");
// Initialize the SPI flash device and print the memory layout
spif.init();
printf("spif size: %llu\n", spif.size());
printf("spif read size: %llu\n", spif.get_read_size());
printf("spif program size: %llu\n", spif.get_program_size());
printf("spif erase size: %llu\n", spif.get_erase_size());
// Write "Hello World!" to the first block
char *buffer = (char*) malloc(spif.get_erase_size());
sprintf(buffer, "Hello World!\n");
spif.erase(0, spif.get_erase_size());
spif.program(buffer, 0, spif.get_erase_size());
// Read back what was stored
spif.read(buffer, 0, spif.get_erase_size());
printf("%s", buffer);
// Deinitialize the device
spif.deinit();
}
Note the following modifications to the original code sample:
- The SPI Flash Driver instance `spif` is given the pin configuration
for the SPI bus from the Arduino header pins D11, D12, D13 and D10,
as noted in the comments.
- The buffer type has been modified to char* to (see line with malloc() above).
The application can be built with the following command:
simhug01@E107851:/d/demo_area/ex_app2$ mbed compile -m K64F -t GCC_ARM 2>&1 | tee build_app_ex_app2_log.txt
Once the binary is built, copy the binary from `/d/demo_area/ex_app2/BUILD/K64F/GCC_ARM/example2.bin` to the K64F.
After connecting a serial console and resetting the target, the following trace should be seen:
spif test
spif size: 2097152
spif read size: 1
spif program size: 1
spif erase size: 4096
Hello World!
## Build the mbed OS Test Cases
If you have completed the previous section "Simple SPIFBlockDevice Example" then first prepare the environment by removing the BUILD
directory and hiding or removing the example2.cpp:
simhug01@E107851:/d/demo_area/ex_app2$ rm -fR BUILD
simhug01@E107851:/d/demo_area/ex_app2$ cp example2.cpp example2_cpp
Build the test cases for the K64F target using the following command:
simhug01@E107851:/d/demo_area/ex_app2$ mbed -v test --compile -t GCC_ARM -m K64F 2>&1 | tee build_tests_gcc_20170322_1007.txt
<trace removed>
simhug01@E107851:/d/demo_area/ex_app2$
The build trace is quite extensive but on a successful build you should see the following output at the end of the log:
Build successes:
* K64F::GCC_ARM::MBED-BUILD
* K64F::GCC_ARM::MBED-OS-FEATURES-FEATURE_LWIP-TESTS-MBEDMICRO-NET-CONNECTIVITY
<trace removed>
* K64F::GCC_ARM::MBED-OS-FEATURES-TESTS-FILESYSTEM-FAT_FILE_SYSTEM
* K64F::GCC_ARM::MBED-OS-FEATURES-TESTS-FILESYSTEM-HEAP_BLOCK_DEVICE
* K64F::GCC_ARM::MBED-OS-FEATURES-TESTS-FILESYSTEM-UTIL_BLOCK_DEVICE
<trace removed>
* K64F::GCC_ARM::MBED-OS-TESTS-STORAGE_ABSTRACTION-BASICAPI
* K64F::GCC_ARM::SPIFLASH-DRIVER-TESTS-BLOCK_DEVICE-SPIF
Build skips:
* K64F::GCC_ARM::MBED-OS-FEATURES-FEATURE_LWIP-TESTS-MBEDMICRO-NET-TCP_PACKET_PRESSURE
<trace removed>
Notice the following test in the spiflash-driver tree listed above:
- `K64F::GCC_ARM::SPIFLASH-DRIVER-TESTS-BLOCK_DEVICE-SPIF`
The SPIFBlockDevice test case is at following locations in the source code tree:
/d/demo_area/ex_app2/spiflash-driver/TESTS/block_device/spif/main.cpp
This provides an example of reading and writing data blocks to the block device interface for the SPI NOR part.
Run the test using the following command:
simhug01@E107851:/d/demo_area/ex_app2$ mbedgt -VS --test-by-names=spiflash-driver-tests-block_device-spif 2>&1 | tee run_test_gcc_20170322_1007.txt
The test output should look similar to the following trace:
(mx_env1) simhug01@E107851:/d/datastore/public/jobs/yr2017/2278/sdh_dev_mx1/ex_app5$ mbedgt -VS --test-by-names=spiflash-driver-tests-block_device-sp
if 2>&1 | tee 2278_run_test_ex_app5_br_master_time_20170322_1207_spif.txt
mbedgt: greentea test automation tool ver. 1.2.5
mbedgt: using multiple test specifications from current directory!
using 'BUILD\tests\K64F\GCC_ARM\test_spec.json'
mbedgt: detecting connected mbed-enabled devices...
mbedgt: detected 1 device
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
| platform_name | platform_name_unique | serial_port | mount_point | target_id |
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
| K64F | K64F[0] | COM46 | E: | 0240000029304e450023500878a3001df131000097969900 |
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
mbedgt: processing target 'K64F' toolchain 'GCC_ARM' compatible platforms... (note: switch set to --parallel 1)
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
| platform_name | platform_name_unique | serial_port | mount_point | target_id |
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
| K64F | K64F[0] | COM46:9600 | E: | 0240000029304e450023500878a3001df131000097969900 |
+---------------+----------------------+-------------+-------------+--------------------------------------------------+
mbedgt: test case filter (specified with -n option)
test filtered in 'spiflash-driver-tests-block_device-spif'
mbedgt: running 1 test for platform 'K64F' and toolchain 'GCC_ARM'
use 1 instance of execution threads for testing
mbedgt: checking for 'host_tests' directory above image directory structure
'host_tests' directory not found: two directory levels above image path checked
mbedgt: selecting test case observer...
calling mbedhtrun: mbedhtrun -m K64F -p COM46:9600 -f "BUILD/tests/K64F/GCC_ARM/spiflash-driver/TESTS/block_device/spif/spif.bin" -d E: -C 4 -
c shell -t 0240000029304e450023500878a3001df131000097969900
mbedgt: mbed-host-test-runner: started
[1490184626.50][HTST][INF] host test executor ver. 1.1.6
[1490184626.50][HTST][INF] copy image onto target...
[1490184626.50][COPY][INF] Waiting up to 60 sec for '0240000029304e450023500878a3001df131000097969900' mount point (current is 'E:')...
1 file(s) copied.
[1490184635.79][HTST][INF] starting host test process...
[1490184636.10][CONN][INF] starting connection process...
[1490184636.10][CONN][INF] notify event queue about extra 60 sec timeout for serial port pooling
[1490184636.10][CONN][INF] initializing serial port listener...
[1490184636.10][PLGN][INF] Waiting up to 60 sec for '0240000029304e450023500878a3001df131000097969900' serial port (current is 'COM46')...
[1490184636.12][HTST][INF] setting timeout to: 60 sec
[1490184636.24][SERI][INF] serial(port=COM46, baudrate=9600, timeout=0.01)
<lines deleted to save space>
[1490184649.90][CONN][INF] found KV pair in stream: {{__testcase_name;Testing read write random blocks}}, queued...
[1490184649.97][CONN][RXD] >>> Running case #1: 'Testing read write random blocks'...
[1490184650.02][CONN][INF] found KV pair in stream: {{__testcase_start;Testing read write random blocks}}, queued...
[1490184650.05][CONN][RXD] read size: 1bytes (1bytes)
[1490184650.08][CONN][RXD] program size: 1bytes (1bytes)
[1490184650.12][CONN][RXD] erase size: 4kbytes (4096bytes)
[1490184650.13][CONN][RXD] total size: 2Mbytes (2097152bytes)
[1490184650.17][CONN][RXD] test 002d000:4096...
[1490184650.36][CONN][RXD] write 002d000:4096 aad8573abd84e79e5e3684fa5519aabb...
[1490184650.50][CONN][RXD] read 002d000:4096 aad8573abd84e79e5e3684fa5519aabb...
[1490184650.56][CONN][RXD] error 002d000:4096 00000000000000000000000000000000
[1490184650.58][CONN][RXD] test 0036000:4096...
[1490184650.77][CONN][RXD] write 0036000:4096 92fc08f5b4113047225a8d3b855e5460...
[1490184650.91][CONN][RXD] read 0036000:4096 92fc08f5b4113047225a8d3b855e5460...
[1490184650.97][CONN][RXD] error 0036000:4096 00000000000000000000000000000000
[1490184650.99][CONN][RXD] test 00c6000:4096...
[1490184651.16][CONN][RXD] write 00c6000:4096 89a030a34b17ca3545c7b007001ef74f...
[1490184651.32][CONN][RXD] read 00c6000:4096 89a030a34b17ca3545c7b007001ef74f...
[1490184651.38][CONN][RXD] error 00c6000:4096 00000000000000000000000000000000
[1490184651.40][CONN][RXD] test 00da000:4096...
[1490184651.60][CONN][RXD] write 00da000:4096 446fd0232a3d053af820b69c614b3662...
[1490184651.73][CONN][RXD] read 00da000:4096 446fd0232a3d053af820b69c614b3662...
[1490184651.79][CONN][RXD] error 00da000:4096 00000000000000000000000000000000
[1490184651.81][CONN][RXD] test 0188000:4096...
[1490184652.00][CONN][RXD] write 0188000:4096 9a36d3c6d4034958cade542a9f1e22c2...
[1490184652.14][CONN][RXD] read 0188000:4096 9a36d3c6d4034958cade542a9f1e22c2...
[1490184652.20][CONN][RXD] error 0188000:4096 00000000000000000000000000000000
[1490184652.21][CONN][RXD] test 015f000:4096...
[1490184652.42][CONN][RXD] write 015f000:4096 70f83b9cc6713736c60089a0fa55f12d...
[1490184652.55][CONN][RXD] read 015f000:4096 70f83b9cc6713736c60089a0fa55f12d...
[1490184652.61][CONN][RXD] error 015f000:4096 00000000000000000000000000000000
[1490184652.63][CONN][RXD] test 005c000:4096...
[1490184652.82][CONN][RXD] write 005c000:4096 47a0f043fda26135877bb11c7b7016dc...
[1490184652.96][CONN][RXD] read 005c000:4096 47a0f043fda26135877bb11c7b7016dc...
[1490184653.02][CONN][RXD] error 005c000:4096 00000000000000000000000000000000
[1490184653.04][CONN][RXD] test 0177000:4096...
[1490184653.24][CONN][RXD] write 0177000:4096 174f13941b6385d4a829f2d066a1e375...
[1490184653.37][CONN][RXD] read 0177000:4096 174f13941b6385d4a829f2d066a1e375...
[1490184653.42][CONN][RXD] error 0177000:4096 00000000000000000000000000000000
[1490184653.45][CONN][RXD] test 0173000:4096...
[1490184653.65][CONN][RXD] write 0173000:4096 383f0ca8cc86e3225362805329e0d659...
[1490184653.78][CONN][RXD] read 0173000:4096 383f0ca8cc86e3225362805329e0d659...
[1490184653.84][CONN][RXD] error 0173000:4096 00000000000000000000000000000000
[1490184653.86][CONN][RXD] test 01d9000:4096...
[1490184654.05][CONN][RXD] write 01d9000:4096 73f32decf08112f271131f9837b76f28...
[1490184654.19][CONN][RXD] read 01d9000:4096 73f32decf08112f271131f9837b76f28...
[1490184654.24][CONN][RXD] error 01d9000:4096 00000000000000000000000000000000
[1490184654.31][CONN][INF] found KV pair in stream: {{__testcase_finish;Testing read write random blocks;1;0}}, queued...
[1490184654.38][CONN][RXD] >>> 'Testing read write random blocks': 1 passed, 0 failed
[1490184654.38][CONN][RXD]
[1490184654.41][CONN][RXD] >>> Test cases: 1 passed, 0 failed
[1490184654.44][CONN][INF] found KV pair in stream: {{__testcase_summary;1;0}}, queued...
[1490184654.47][CONN][INF] found KV pair in stream: {{max_heap_usage;0}}, queued...
[1490184654.48][CONN][INF] found KV pair in stream: {{end;success}}, queued...
[1490184654.48][HTST][ERR] orphan event in main phase: {{max_heap_usage;0}}, timestamp=1490184654.467000
[1490184654.48][HTST][INF] __notify_complete(True)
[1490184654.50][CONN][INF] found KV pair in stream: {{__exit;0}}, queued...
[1490184654.51][HTST][INF] __exit(0)
[1490184654.52][HTST][INF] __exit_event_queue received
[1490184654.52][HTST][INF] test suite run finished after 4.75 sec...
[1490184654.53][CONN][INF] received special even '__host_test_finished' value='True', finishing
[1490184654.53][HTST][INF] CONN exited with code: 0
[1490184654.53][HTST][INF] No events in queue
[1490184654.53][HTST][INF] stopped consuming events
[1490184654.53][HTST][INF] host test result() call skipped, received: True
[1490184654.53][HTST][INF] calling blocking teardown()
[1490184654.53][HTST][INF] teardown() finished
[1490184654.53][HTST][INF] {{result;success}}
mbedgt: checking for GCOV data...
mbedgt: mbed-host-test-runner: stopped and returned 'OK'
mbedgt: test on hardware with target id: 0240000029304e450023500878a3001df131000097969900
mbedgt: test suite 'spiflash-driver-tests-block_device-spif' ......................................... OK in 28.42 sec
test case: 'Testing read write random blocks' ................................................ OK in 4.29 sec
mbedgt: test case summary: 1 pass, 0 failures
mbedgt: all tests finished!
mbedgt: shuffle seed: 0.0217829158
mbedgt: test suite report:
+--------------+---------------+-----------------------------------------+--------+--------------------+-------------+
| target | platform_name | test suite | result | elapsed_time (sec) | copy_method |
+--------------+---------------+-----------------------------------------+--------+--------------------+-------------+
| K64F-GCC_ARM | K64F | spiflash-driver-tests-block_device-spif | OK | 28.42 | shell |
+--------------+---------------+-----------------------------------------+--------+--------------------+-------------+
mbedgt: test suite results: 1 OK
mbedgt: test case report:
+--------------+---------------+-----------------------------------------+----------------------------------+--------+--------+--------+--------------------+
| target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) |
+--------------+---------------+-----------------------------------------+----------------------------------+--------+--------+--------+--------------------+
| K64F-GCC_ARM | K64F | spiflash-driver-tests-block_device-spif | Testing read write random blocks | 1 | 0 | OK | 4.29 |
+--------------+---------------+-----------------------------------------+----------------------------------+--------+--------+--------+--------------------+
mbedgt: test case results: 1 OK
mbedgt: completed in 35.04 sec
(mx_env1) simhug01@E107851:/d/datastore/public/jobs/yr2017/2278/sdh_dev_mx1/ex_app5$
# Appendix 2: Getting Started With The I2C EEPROM Driver
Hardware required:
- K64F.
- CI test shield.
- Micro USB cable.
Software required:
- mbed CLI (with all other dependencies installed).
- ARMCC / GCC / IAR compiler.
- mbed greentea.
- git account.
Github repos to use:
- The [mbed OS repository](https://github.com/armmbed/mbed-os)
- The [I2C EEPROM driver repository](https://github.com/ARMmbed/i2ceeprom-driver.git)
- The [CI test shield repository](https://github.com/ARMmbed/ci-test-shield.git) for `mbed_app.json` application configuration file.
Steps to follow:
- Create an empty example project in a suitable directory. Move into it.
- Download mbed OS into the example directory via `mbed new .`
- Add the I2C EEPROM driver via `mbed add i2ceeprom-driver`
- Clone the CI test shield repository to another suitable directory. Copy the mbed_app.json
from the CI test shield directory to the top level of the newly created example directory.
- Make sure the I2C pins are SDA on D14 and SCL on D15 and the I2C EEPROM slave address is
0xA0 in the mbed_app.json that you just copied.
- Connect the target to the host machine. Run `mbed detect` to make sure the target is detected.
- Now we are ready to run the greentea tests on this target with
`mbed test -t ARM -m K64F -n i2ceeprom-driver-tests-block_device-i2cee -v`
- Note that the greentea test above makes use of the main.cpp supplied in the
`TESTS\block_device\i2cee` directory. You can customize this if required or use your own test
application via main.cpp. Be sure to have only 1 main(). If using a custom main() then you
can either have this in the TESTS directory or at the top level example directory.
- The tests should pass. If not, time to debug!!
- For other targets, please change the target ID string in the test command above to the
appropriate one. You can check the supported targets from mbed CLI using `mbed target --supported`.
The output should be like this:
Building library mbed-build (K64F, ARM)
Scan: i2c_ex1
Scan: FEATURE_BLE
Scan: FEATURE_COMMON_PAL
Scan: FEATURE_LWIP
Scan: FEATURE_UVISOR
Scan: FEATURE_ETHERNET_HOST
Scan: FEATURE_LOWPAN_BORDER_ROUTER
Scan: FEATURE_LOWPAN_HOST
Scan: FEATURE_LOWPAN_ROUTER
Scan: FEATURE_NANOSTACK
Scan: FEATURE_NANOSTACK_FULL
Scan: FEATURE_THREAD_BORDER_ROUTER
Scan: FEATURE_THREAD_END_DEVICE
Scan: FEATURE_THREAD_ROUTER
Scan: FEATURE_STORAGE
Scan: ARM
Scan: FEATURE_LWIP
Scan: FEATURE_STORAGE
Building project i2cee (K64F, ARM)
Scan: ARM
Scan: FEATURE_LWIP
Scan: FEATURE_STORAGE
Scan: i2cee
+-----------+-------+-------+-------+
| Module | .text | .data | .bss |
+-----------+-------+-------+-------+
| Misc | 49473 | 420 | 11628 |
| Subtotals | 49473 | 420 | 11628 |
+-----------+-------+-------+-------+
Allocated Heap: unknown
Allocated Stack: unknown
Total Static RAM memory (data + bss): 12048 bytes
Total RAM memory (data + bss + heap + stack): 12048 bytes
Total Flash memory (text + data + misc): 49893 bytes
Image: BUILD/tests/K64F/ARM/i2ceeprom-driver/TESTS/block_device/i2cee/i2cee.bin
Memory map breakdown for built projects (values in Bytes):
+-------+--------+-----------+------------+-------+------+-----------+-------------+
| name | target | toolchain | static_ram | stack | heap | total_ram | total_flash |
+-------+--------+-----------+------------+-------+------+-----------+-------------+
| i2cee | K64F | ARM | 12048 | 0 | 0 | 12048 | 49893 |
+-------+--------+-----------+------------+-------+------+-----------+-------------+
Build successes:
* K64F::ARM::I2CEEPROM-DRIVER-TESTS-BLOCK_DEVICE-I2CEE
* K64F::ARM::MBED-BUILD
mbedgt: greentea test automation tool ver. 1.2.5
mbedgt: test specification file 'C:\Ashok\SiPWorkshop\Filesystem\i2c_ex1\BUILD\tests\K64F\ARM\test_spec.json' (specified with --test-spec option)
mbedgt: using 'C:\Ashok\SiPWorkshop\Filesystem\i2c_ex1\BUILD\tests\K64F\ARM\test_spec.json' from current directory!
mbedgt: detecting connected mbed-enabled devices...
mbedgt: detected 1 device
mbedgt: processing target 'K64F' toolchain 'ARM' compatible platforms... (note: switch set to --parallel 1)
mbedgt: test case filter (specified with -n option)
test filtered in 'i2ceeprom-driver-tests-block_device-i2cee'
mbedgt: running 1 test for platform 'K64F' and toolchain 'ARM'
mbedgt: mbed-host-test-runner: started
mbedgt: checking for GCOV data...
mbedgt: test on hardware with target id: 0240000034544e45002600048e3800285a91000097969900
mbedgt: test suite 'i2ceeprom-driver-tests-block_device-i2cee' ....................................... OK in 11.79 sec
test case: 'Testing read write random blocks' ................................................ OK in 1.23 sec
mbedgt: test case summary: 1 pass, 0 failures
mbedgt: all tests finished!
mbedgt: shuffle seed: 0.1529521449
mbedgt: test suite report:
+----------+---------------+-------------------------------------------+--------+--------------------+-------------+
| target | platform_name | test suite | result | elapsed_time (sec) | copy_method |
+----------+---------------+-------------------------------------------+--------+--------------------+-------------+
| K64F-ARM | K64F | i2ceeprom-driver-tests-block_device-i2cee | OK | 11.79 | shell |
+----------+---------------+-------------------------------------------+--------+--------------------+-------------+
mbedgt: test suite results: 1 OK
mbedgt: test case report:
+----------+---------------+-------------------------------------------+----------------------------------+--------+--------+--------+--------------------+
| target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) |
+----------+---------------+-------------------------------------------+----------------------------------+--------+--------+--------+--------------------+
| K64F-ARM | K64F | i2ceeprom-driver-tests-block_device-i2cee | Testing read write random blocks | 1 | 0 | OK | 1.23 |
+----------+---------------+-------------------------------------------+----------------------------------+--------+--------+--------+--------------------+
mbedgt: test case results: 1 OK
mbedgt: completed in 13.30 sec

View File

@ -1,43 +0,0 @@
# SPI Flash Driver
Block device driver for NOR based SPI flash devices that support SFDP.
NOR based SPI flash supports byte-sized read and writes, with an erase size of around 4kbytes. An erase sets a block to all 1s, with successive writes clearing set bits.
More info on NOR flash can be found on wikipedia:
https://en.wikipedia.org/wiki/Flash_memory#NOR_memories
``` cpp
// Here's an example using the MX25R SPI flash device on the K82F
#include "mbed.h"
#include "SPIFBlockDevice.h"
// Create flash device on SPI bus with PTE5 as chip select
SPIFBlockDevice spif(PTE2, PTE4, PTE1, PTE5);
int main()
{
printf("spif test\n");
// Initialize the SPI flash device and print the memory layout
spif.init();
printf("spif size: %llu\n", spif.size());
printf("spif read size: %llu\n", spif.get_read_size());
printf("spif program size: %llu\n", spif.get_program_size());
printf("spif erase size: %llu\n", spif.get_erase_size());
// Write "Hello World!" to the first block
uint8_t *buffer = malloc(spif.get_erase_size());
sprintf(buffer, "Hello World!\n");
spif.erase(0, spif.get_erase_size());
spif.program(buffer, 0, spif.get_erase_size());
// Read back what was stored
spif.read(buffer, 0, spif.get_erase_size());
printf("%s", buffer);
// Deinitialize the device
spif.deinit();
}
```

View File

@ -1,348 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2016 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "SPIFBlockDevice.h"
// Read/write/erase sizes
#define SPIF_READ_SIZE 1
#define SPIF_PROG_SIZE 1
#define SPIF_SE_SIZE 4096
#define SPIF_TIMEOUT 10000
// Debug available
#define SPIF_DEBUG 0
#define SPIF_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
#define SPIF_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
#define SPIF_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
#define SPIF_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
#define SPIF_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
#define SPIF_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
// MX25R Series Register Command Table.
enum ops {
SPIF_NOP = 0x00, // No operation
SPIF_READ = 0x03, // Read data
SPIF_PROG = 0x02, // Program data
SPIF_SE = 0x20, // 4KB Sector Erase
SPIF_CE = 0xc7, // Chip Erase
SPIF_SFDP = 0x5a, // Read SFDP
SPIF_WREN = 0x06, // Write Enable
SPIF_WRDI = 0x04, // Write Disable
SPIF_RDSR = 0x05, // Read Status Register
SPIF_RDID = 0x9f, // Read Manufacturer and JDEC Device ID
};
// Status register from RDSR
// [- stuff -| wel | wip ]
// [- 6 -| 1 | 1 ]
#define SPIF_WEL 0x2
#define SPIF_WIP 0x1
SPIFBlockDevice::SPIFBlockDevice(
PinName mosi, PinName miso, PinName sclk, PinName cs, int freq)
: _spi(mosi, miso, sclk), _cs(cs), _size(0)
{
_cs = 1;
_spi.frequency(freq);
}
int SPIFBlockDevice::init()
{
// Check for vendor specific hacks, these should move into more general
// handling when possible. RDID is not used to verify a device is attached.
uint8_t id[3];
_cmdread(SPIF_RDID, 0, 3, 0x0, id);
switch (id[0]) {
case 0xbf:
// SST devices come preset with block protection
// enabled for some regions, issue gbpu instruction to clear
_wren();
_cmdwrite(0x98, 0, 0, 0x0, NULL);
break;
}
// Check that device is doing ok
int err = _sync();
if (err) {
return SPIF_BLOCK_DEVICE_ERROR_NO_DEVICE;
}
// Check JEDEC serial flash discoverable parameters for device
// specific info
uint8_t header[16];
_cmdread(SPIF_SFDP, 4, 16, 0x0, header);
// Verify SFDP signature for sanity
// Also check that major/minor version is acceptable
if (!(memcmp(&header[0], "SFDP", 4) == 0 && header[5] == 1)) {
return BD_ERROR_DEVICE_ERROR;
}
// The SFDP spec indicates the standard table is always at offset 0
// in the parameter headers, we check just to be safe
if (!(header[8] == 0 && header[10] == 1)) {
return BD_ERROR_DEVICE_ERROR;
}
// Parameter table pointer, spi commands are BE, SFDP is LE,
// also sfdp command expects extra read wait byte
uint32_t table_addr = (
(header[14] << 24) |
(header[13] << 16) |
(header[12] << 8 ));
uint8_t table[8];
_cmdread(SPIF_SFDP, 4, 8, table_addr, table);
// Check erase size, currently only supports 4kbytes
// TODO support erase size != 4kbytes?
// TODO support other erase opcodes from the sector descriptions
if ((table[0] & 0x3) != 0x1 || table[1] != SPIF_SE) {
return BD_ERROR_DEVICE_ERROR;
}
// Check address size, currently only supports 3byte addresses
// TODO support address > 3bytes?
// TODO check for devices larger than 2Gbits?
if ((table[2] & 0x4) != 0 || (table[7] & 0x80) != 0) {
return BD_ERROR_DEVICE_ERROR;
}
// Get device density, stored as size in bits - 1
uint32_t density = (
(table[7] << 24) |
(table[6] << 16) |
(table[5] << 8 ) |
(table[4] << 0 ));
_size = (density/8) + 1;
return 0;
}
int SPIFBlockDevice::deinit()
{
// Latch write disable just to keep noise
// from changing the device
_cmdwrite(SPIF_WRDI, 0, 0, 0x0, NULL);
return 0;
}
void SPIFBlockDevice::_cmdread(
uint8_t op, uint32_t addrc, uint32_t retc,
uint32_t addr, uint8_t *rets)
{
_cs = 0;
_spi.write(op);
for (uint32_t i = 0; i < addrc; i++) {
_spi.write(0xff & (addr >> 8*(addrc-1 - i)));
}
for (uint32_t i = 0; i < retc; i++) {
rets[i] = _spi.write(0);
}
_cs = 1;
if (SPIF_DEBUG) {
printf("spif <- %02x", op);
for (uint32_t i = 0; i < addrc; i++) {
if (i < addrc) {
printf("%02lx", 0xff & (addr >> 8*(addrc-1 - i)));
} else {
printf(" ");
}
}
printf(" ");
for (uint32_t i = 0; i < 16 && i < retc; i++) {
printf("%02x", rets[i]);
}
if (retc > 16) {
printf("...");
}
printf("\n");
}
}
void SPIFBlockDevice::_cmdwrite(
uint8_t op, uint32_t addrc, uint32_t argc,
uint32_t addr, const uint8_t *args)
{
_cs = 0;
_spi.write(op);
for (uint32_t i = 0; i < addrc; i++) {
_spi.write(0xff & (addr >> 8*(addrc-1 - i)));
}
for (uint32_t i = 0; i < argc; i++) {
_spi.write(args[i]);
}
_cs = 1;
if (SPIF_DEBUG) {
printf("spif -> %02x", op);
for (uint32_t i = 0; i < addrc; i++) {
if (i < addrc) {
printf("%02lx", 0xff & (addr >> 8*(addrc-1 - i)));
} else {
printf(" ");
}
}
printf(" ");
for (uint32_t i = 0; i < 16 && i < argc; i++) {
printf("%02x", args[i]);
}
if (argc > 16) {
printf("...");
}
printf("\n");
}
}
int SPIFBlockDevice::_sync()
{
for (int i = 0; i < SPIF_TIMEOUT; i++) {
// Read status register until write not-in-progress
uint8_t status;
_cmdread(SPIF_RDSR, 0, 1, 0x0, &status);
// Check WIP bit
if (!(status & SPIF_WIP)) {
return 0;
}
wait_ms(1);
}
return BD_ERROR_DEVICE_ERROR;
}
int SPIFBlockDevice::_wren()
{
_cmdwrite(SPIF_WREN, 0, 0, 0x0, NULL);
for (int i = 0; i < SPIF_TIMEOUT; i++) {
// Read status register until write latch is enabled
uint8_t status;
_cmdread(SPIF_RDSR, 0, 1, 0x0, &status);
// Check WEL bit
if (status & SPIF_WEL) {
return 0;
}
wait_ms(1);
}
return BD_ERROR_DEVICE_ERROR;
}
int SPIFBlockDevice::read(void *buffer, bd_addr_t addr, bd_size_t size)
{
// Check the address and size fit onto the chip.
if (!is_valid_read(addr, size)) {
return SPIF_BLOCK_DEVICE_ERROR_PARAMETER;
}
_cmdread(SPIF_READ, 3, size, addr, static_cast<uint8_t *>(buffer));
return 0;
}
int SPIFBlockDevice::program(const void *buffer, bd_addr_t addr, bd_size_t size)
{
// Check the address and size fit onto the chip.
if (!is_valid_program(addr, size)) {
return SPIF_BLOCK_DEVICE_ERROR_PARAMETER;
}
while (size > 0) {
int err = _wren();
if (err) {
return err;
}
// Write up to 256 bytes a page
// TODO handle unaligned programs
uint32_t off = addr % 256;
uint32_t chunk = (off + size < 256) ? size : (256-off);
_cmdwrite(SPIF_PROG, 3, chunk, addr, static_cast<const uint8_t *>(buffer));
buffer = static_cast<const uint8_t*>(buffer) + chunk;
addr += chunk;
size -= chunk;
wait_ms(1);
err = _sync();
if (err) {
return err;
}
}
return 0;
}
int SPIFBlockDevice::erase(bd_addr_t addr, bd_size_t size)
{
// Check the address and size fit onto the chip.
if (!is_valid_erase(addr, size)) {
return SPIF_BLOCK_DEVICE_ERROR_PARAMETER;
}
while (size > 0) {
int err = _wren();
if (err) {
return err;
}
// Erase 4kbyte sectors
// TODO support other erase sizes?
uint32_t chunk = 4096;
_cmdwrite(SPIF_SE, 3, 0, addr, NULL);
addr += chunk;
size -= chunk;
err = _sync();
if (err) {
return err;
}
}
return 0;
}
bd_size_t SPIFBlockDevice::get_read_size() const
{
return SPIF_READ_SIZE;
}
bd_size_t SPIFBlockDevice::get_program_size() const
{
return SPIF_PROG_SIZE;
}
bd_size_t SPIFBlockDevice::get_erase_size() const
{
return SPIF_SE_SIZE;
}
bd_size_t SPIFBlockDevice::size() const
{
return _size;
}

View File

@ -1,155 +0,0 @@
/* mbed Microcontroller Library
* Copyright (c) 2016 ARM Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_SPIF_BLOCK_DEVICE_H
#define MBED_SPIF_BLOCK_DEVICE_H
/* If the target has no SPI support then SPIF is not supported */
#ifdef DEVICE_SPI
#include <mbed.h>
#include "BlockDevice.h"
/** BlockDevice for SPI based flash devices
* such as the MX25R or SST26F016B
*
* @code
* #include "mbed.h"
* #include "SPIFBlockDevice.h"
*
* // Create mx25r on SPI bus with PTE5 as chip select
* SPIFBlockDevice mx25r(PTE2, PTE4, PTE1, PTE5);
*
* int main() {
* printf("mx25r test\n");
* mx52r.init();
* printf("mx25r size: %llu\n", mx25r.size());
* printf("mx25r read size: %llu\n", mx25r.get_read_size());
* printf("mx25r program size: %llu\n", mx25r.get_program_size());
* printf("mx25r erase size: %llu\n", mx25r.get_erase_size());
*
* uint8_t *buffer = malloc(mx25r.get_erase_size());
* sprintf(buffer, "Hello World!\n");
* mx25r.erase(0, mx25r.get_erase_size());
* mx25r.program(buffer, 0, mx25r.get_erase_size());
* mx25r.read(buffer, 0, mx25r.get_erase_size());
* printf("%s", buffer);
*
* mx25r.deinit();
* }
*/
class SPIFBlockDevice : public BlockDevice
{
public:
/** Creates a SPIFBlockDevice on a SPI bus specified by pins
*
* @param mosi SPI master out, slave in pin
* @param miso SPI master in, slave out pin
* @param sclk SPI clock pin
* @param csel SPI chip select pin
* @param freq Clock speed of the SPI bus (defaults to 40MHz)
*/
SPIFBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName csel, int freq=4000000);
/** Initialize a block device
*
* @return 0 on success or a negative error code on failure
*/
virtual int init();
/** Deinitialize a block device
*
* @return 0 on success or a negative error code on failure
*/
virtual int deinit();
/** Read blocks from a block device
*
* @param buffer Buffer to write blocks to
* @param addr Address of block to begin reading from
* @param size Size to read in bytes, must be a multiple of read block size
* @return 0 on success, negative error code on failure
*/
virtual int read(void *buffer, bd_addr_t addr, bd_size_t size);
/** Program blocks to a block device
*
* The blocks must have been erased prior to being programmed
*
* @param buffer Buffer of data to write to blocks
* @param addr Address of block to begin writing to
* @param size Size to write in bytes, must be a multiple of program block size
* @return 0 on success, negative error code on failure
*/
virtual int program(const void *buffer, bd_addr_t addr, bd_size_t size);
/** Erase blocks on a block device
*
* The state of an erased block is undefined until it has been programmed
*
* @param addr Address of block to begin erasing
* @param size Size to erase in bytes, must be a multiple of erase block size
* @return 0 on success, negative error code on failure
*/
virtual int erase(bd_addr_t addr, bd_size_t size);
/** Get the size of a readable block
*
* @return Size of a readable block in bytes
*/
virtual bd_size_t get_read_size() const;
/** Get the size of a programable block
*
* @return Size of a programable block in bytes
* @note Must be a multiple of the read size
*/
virtual bd_size_t get_program_size() const;
/** Get the size of a eraseable block
*
* @return Size of a eraseable block in bytes
* @note Must be a multiple of the program size
*/
virtual bd_size_t get_erase_size() const;
/** Get the total size of the underlying device
*
* @return Size of the underlying device in bytes
*/
virtual bd_size_t size() const;
private:
// Master side hardware
SPI _spi;
DigitalOut _cs;
// Device configuration discovered through sfdp
bd_size_t _size;
// Internal functions
int _wren();
int _sync();
void _cmdread(uint8_t op, uint32_t addrc, uint32_t retc,
uint32_t addr, uint8_t *rets);
void _cmdwrite(uint8_t op, uint32_t addrc, uint32_t argc,
uint32_t addr, const uint8_t *args);
};
#endif /* DEVICE_SPI */
#endif /* MBED_SPIF_BLOCK_DEVICE_H */