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

drivers: flash: Add one byte read write emulation to qspi nor nrf #305

Merged
merged 7 commits into from
May 29, 2020

Conversation

sigvartmh
Copy link
Contributor

Adds the functionality of doing one byte read and write to QSPI nor
driver. This is achived through the use of stack in the function calls.

It also adds the functionality of using stack if the data passed to the
driver are stored in flash and not in RAM. So that the DMA will still
work if you refrence data in flash by copying the data onto the stack.

Signed-off-by: Sigvart Hovland sigvart.hovland@nordicsemi.no

@sigvartmh sigvartmh requested a review from nvlsianpu May 18, 2020 22:50
@sigvartmh sigvartmh requested a review from pabigot as a code owner May 18, 2020 22:50
@sigvartmh
Copy link
Contributor Author

sigvartmh commented May 18, 2020

Couldn't do it the same way as the nrf soc flash driver as nrfx does not expose a nrfx_nvmc_bytes_write function for QSPI but I changed the implementation to use stack instead of heap.

So some more clarification for this PR. The goal of this PR is to make sure that we can use MCUBoot with external flash. What is needed for that to work is the possibility of doing

  • 1 byte access read/write to memory
  • Write const data which are resides in FLASH not RAM

@sigvartmh sigvartmh self-assigned this May 18, 2020
@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch 2 times, most recently from 511941e to abf4777 Compare May 18, 2020 22:59
@sigvartmh sigvartmh modified the milestones: 1.3, next May 18, 2020
@NordicBuilder
Copy link
Contributor

NordicBuilder commented May 18, 2020

All checks are passing now.

checkpatch (informational only, not a failure)

-:304: WARNING:LONG_LINE: line over 80 characters
#304: FILE: drivers/flash/nrf_qspi_nor.c:609:
+	} else if (IS_ENABLED(CONFIG_NORDIC_QSPI_NOR_FLASH_ALLOW_STACK_USAGE_FOR_DATA_IN_FLASH) &&

- total: 0 errors, 1 warnings, 295 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

Your patch has style problems, please review.

NOTE: Ignored message types: AVOID_EXTERNS BRACES CONFIG_EXPERIMENTAL CONST_STRUCT DATE_TIME FILE_PATH_CHANGES MINMAX NETWORKING_BLOCK_COMMENT_STYLE PRINTK_WITHOUT_KERN_LEVEL SPDX_LICENSE_TAG SPLIT_STRING VOLATILE

NOTE: If any of the errors are false positives, please report
      them to the maintainers.

Tip: The bot edits this comment instead of posting a new one, so you can check the comment's history to see earlier messages.

@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch 2 times, most recently from 3245877 to ed0de5b Compare May 19, 2020 05:54
@kamlaz
Copy link
Contributor

kamlaz commented May 19, 2020

I have looked into your code and I have one question. Your solution provides possibility of writting less than four bytes, but in fact it writes four bytes, but vacants are filled with 0xFF pattern. It is OK when we assume that the data overwritten with mentioned pattern is not needed anymore. What about this scenario: You would like to write 1 byte to some address.

  1. Read four bytes from desired address and copy them to the buffer.
  2. Copy data to write to the buffer that contains data that is present in flash. Using this we overwrite only first byte, the rest (three bytes) remains the same.
  3. Write this 4 byte buffer to the memory.
    I am not sure if this case is useful. What do you think about it?

Copy link
Contributor

@pabigot pabigot left a comment

Choose a reason for hiding this comment

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

Apparently I never posted this.

drivers/flash/nrf_qspi_nor.c Outdated Show resolved Hide resolved
@sigvartmh
Copy link
Contributor Author

Sure I can add back the read, copy and write version.

@pabigot
Copy link
Contributor

pabigot commented May 19, 2020

I have looked into your code and I have one question. Your solution provides possibility of writting less than four bytes, but in fact it writes four bytes, but vacants are filled with 0xFF pattern. It is OK when we assume that the data overwritten with mentioned pattern is not needed anymore.

Is that really what happens? If the underlying device is a standard SPI NOR, then doesn't writing 0xFF to a location leave it unchanged (because write only clears 1s to 0s, not sets 0s to 1s)? In that case you could write 0x01FFFFFF, 0xFF02FFFF, 0xFFFF03FF, 0xFFFFFF04 to the same address in four separate transactions and read back 0x01020304.

I guess if the erase value of the device could be 0x00 then it'd be wrong and you'd need a read, set, write.

@sigvartmh
Copy link
Contributor Author

I guess if the erase value of the device could be 0x00 then it'd be wrong and you'd need a read, set, write.

Yeah, it could be that I made a wrong assumption there expecting no-op for 0xFF it could be that the SPI controller will interpret it differently.

The one on board the DK works the way you would expect. By having 0xFF as no-op and 0xFFFFFFFF as the erase word

@pabigot
Copy link
Contributor

pabigot commented May 19, 2020

The question is whether the QSPI peripheral supports devices with an erase value of zero. I don't see any reason in principle why it wouldn't.

I've re-opened my upstream PR which would make mcuboot work in 2.3.0 if it got merged; it doesn't try to support sub-word writes, only reads, and only at word boundaries (which could be easily fixed).

@carlescufi carlescufi requested a review from de-nordic May 19, 2020 15:38
@sigvartmh
Copy link
Contributor Author

My suggestion is to rework it a bit. I think I've identified 1 issue I need to fix and have this as a [nrf temphack] since I require more than what is suggested upstream. Then rework the QSPI NOR so that it fulfills the requirements of zephyrproject-rtos/zephyr#23628

Then the [nrf temphack] can be removed.

@sigvartmh
Copy link
Contributor Author

Since zephyrproject-rtos/zephyr#25292 has been merged I'll add that commit I assume that it will come in the upmerge and just focus on the write part.

@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch 3 times, most recently from a15594e to d993da7 Compare May 25, 2020 10:53
@sigvartmh sigvartmh modified the milestones: next, 1.3 May 25, 2020
@oyvindronningstad
Copy link
Contributor

I'd prefer we remove the config, but I can live with this as it is. Thanks for all the changes.

I think it's best not to give users any surprise behavior they haven't opted in for.

I'm not familiar with the existing QSPI driver, what is the surprise?

The speed penalty of using data in flash. Due to the small size copy.

Is that less surprising than an error?

Yes, if you get the error you can chose either apply workaround or copy your data locally and pass it to the drive.

Ok, make sure the error is well documented, and mentions the config, so the user knows the choice they have.

@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch from 9fe6547 to 225a976 Compare May 28, 2020 08:45
@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch 2 times, most recently from 8285e3e to ed051d0 Compare May 28, 2020 09:59
@pabigot pabigot self-requested a review May 28, 2020 13:03
help
When this option is enabled writing data from FLASH is possible.
However the driver will use stack to copy the data from flash onto
the stack then start the DMA transfer. If you get an -EINVALID error
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for adding. If you have the time, it would be better to have this documentation in the header file for qspi_nor_write, since I think that's where the user will look if they get the error, but it's not a must.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okei I'll try to move the information there.

@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch 2 times, most recently from da16417 to 00b0cb6 Compare May 29, 2020 08:48
pabigot and others added 6 commits May 29, 2020 13:17
mcuboot and possibly other tools read single byte values to determine
the state of objects.  Rather than fail to do the read of values too
short for this peripheral detect the situation and read into a stack
buffer that meets the length criteria, and on success copy the data
into the provided buffer.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Adds the functionality of doing one byte write to QSPI nor
driver. This is achived through the use of stack in the function calls.

Can be removed when requirements in
zephyrproject-rtos/zephyr#23628
are fulfilled in the QSPI NOR driver.

NCSDK-4628

Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
…lash

Added option which allows you to write data directly from flash by using
stack in the driver. If the data passed to driver resides in flash it
will copy the data to an equally sized stack buffer and pass it to the
QSPI DMA which requires the data to be stored in RAM.

NCSDK-4628

Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
The check for small transfers inadvertently allowed a transfer of zero
bytes, which should be an error (invalid parameter).

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
Having a completion wait function release a lock internally only when
the operation fails is confusing.  Remove that feature, and make the
lock and unlock operations explicit and paired.

This makes it much more clear how to properly handle transactions that
require multiple calls to the HAL.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Signed-off-by: Sigvart Hovland <sigvart.m@gmail.com>
A write of sub-word data requires reading the content currently at the
target offset so that a word-sized write doesn't change it.
Correctness requires no other thread be given an opportunity to change
that data before the subsequent write is performed.

Extend the wait API to allow a lock to be retained after a failed
operation.  Rework the write control flow to allow success in the read
to continue to the write without unlocking, while failure in the read
bypasses the write.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
@sigvartmh sigvartmh force-pushed the fix/qspi-nor-driver branch from 00b0cb6 to 8b77e6a Compare May 29, 2020 11:17
The ZephyrBuildConfiguration package allow downstream users to control
the Zephyr build system using a cmake package.

A Zephyr Build Configuration package allows for setting of additional
DTS_ROOT, BOARD_ROOT, and similar variables without having to patch
Zephyr repo, but it also allows for inclusion of additional boilerplate
code for more advanced use cases.

The repository or folder containing the Zephyr Build Configuration
package must be on toplevel in the Zephyr workspace.

Signed-off-by: Torsten Rasmussen <Torsten.Rasmussen@nordicsemi.no>
@nvlsianpu
Copy link
Contributor

@sigvartmh Will be this upstreamed?

@sigvartmh
Copy link
Contributor Author

sigvartmh commented Jun 4, 2020

@nvlsianpu all of it? or just sub-word write @pabigot zephyrproject-rtos/zephyr#25971 made an upstream PR it seems.

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

Successfully merging this pull request may close these issues.

10 participants