-
Notifications
You must be signed in to change notification settings - Fork 3k
Feature: Flash IAP c++ class addition #3700
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
Conversation
|
||
} | ||
|
||
int FlashIAP::init() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opinions for return types, own enum ? We have int
for the core classes but I have seen some new classes go towards defining own types that are descriptive and more readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think typdefs help document the intent of different parts of the function declaration:
flash_error_t FlashIAP::read(void *buffer, flash_addr_t addr, flash_size_t size);
However I don't think the error return should be an enum. It allows compilation warnings, but prevents cross module errors and the strict casting rules of c++ limit compatibility with simple ints (which I don't think is unreasonable for users to use). Keeping error types a typedef of int allows -1 as a "miscellaneous" error and gradual adoption of more useful error codes.
Just my 2c, the new classes do diverge here, so a different perspective may be valuable.
drivers/FlashIAP.cpp
Outdated
uint32_t count = size; | ||
uint8_t *flash_pointer = (uint8_t *)addr; | ||
uint8_t *read_buffer = (uint8_t *)buffer; | ||
while (count) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiousity, why not memcpy? memcpy(buffer, (const void*)addr, size)
drivers/FlashIAP.cpp
Outdated
return -1; | ||
} | ||
|
||
if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Why not just call program? Keeps you from repeating yourself.
drivers/FlashIAP.cpp
Outdated
|
||
int FlashIAP::erase(uint32_t addr, uint32_t size) | ||
{ | ||
MBED_ASSERT((flash_get_sector_size(&_flash, addr) % size) == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably also check alignment? (addr / sector_size) * sector_size == addr
Nice work so far 👍 Out of curiousity, how would a user get the range of addresses a FlashIAP covers? |
drivers/FlashIAP.h
Outdated
FlashIAP(); | ||
~FlashIAP(); | ||
|
||
/** Initialize a flash block device |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the expected behavior if this function is called twice in a row ? Is it authorized ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added comment - required to be called just once per lifetime of an object
namespace mbed { | ||
|
||
/** \addtogroup drivers */ | ||
/** @{*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you comment on the expected thread safety of the class ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add it
drivers/FlashIAP.h
Outdated
|
||
/** Write blocks to a block device | ||
* | ||
* A write is equivalent to an erase followed by a program |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you indicate that in case of error, during the operation. If the data has been erased they are not recovered ?
drivers/FlashIAP.cpp
Outdated
|
||
int FlashIAP::erase(uint32_t addr, uint32_t size) | ||
{ | ||
MBED_ASSERT((flash_get_sector_size(&_flash, addr) % size) == 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why should it be an assertion rather than a true precondition check which returns an error ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking addr
alignment to block address might be a good thing.
} | ||
|
||
int FlashIAP::program(const void *buffer, uint32_t addr, uint32_t size) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it valuable to check addr
block alignment and size
size ?
drivers/FlashIAP.h
Outdated
* @param size Size to read in bytes, must be a multiple of read block size | ||
* @return 0 on success, negative error code on failure | ||
*/ | ||
int read(void *buffer, uint32_t addr, uint32_t size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this member function can be tagged as const.
drivers/FlashIAP.h
Outdated
* | ||
* @return Size of a sector in bytes | ||
*/ | ||
uint32_t get_sector_size(uint32_t addr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this member function can be tagged as const.
drivers/FlashIAP.h
Outdated
* | ||
* @return Size of the underlying device in bytes | ||
*/ | ||
uint32_t get_flash_size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this member function can be tagged as const.
drivers/FlashIAP.h
Outdated
* | ||
* @return Size of a program page in bytes | ||
*/ | ||
uint32_t get_page_size(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this member function can be tagged as const.
hal/flash_api.h
Outdated
* @param obj The flash objects | ||
* @return The size of the flash available | ||
*/ | ||
uint32_t flash_get_size(flash_t *obj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const flash_t *obj
?
TESTS/mbed_drivers/flashiap/main.cpp
Outdated
uint32_t sector_size = flash_device.get_sector_size(flash_device.get_flash_size() - 1UL); | ||
TEST_ASSERT_NOT_EQUAL(sector_size, 0); | ||
const uint8_t test_value = 0xCE; | ||
uint8_t *data = new uint8_t[sector_size]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be deleted after use. Same for a couple calls below too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, good catch !
drivers/FlashIAP.cpp
Outdated
if (ret != 0) { | ||
return -1 ; | ||
} | ||
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good to check or assert sector size in a loop either here or above. If sector size gets bigger then size could underflow.
ed88d74
to
1b803af
Compare
Thanks for the review @geky @pan- @c1728p9 , I should have responded to all of them.
|
dcccccf
to
110ce9c
Compare
110ce9c
to
697afbc
Compare
Please review again, I would like to have this on the feature branch :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from the missing lock release it looks good to me.
drivers/FlashIAP.cpp
Outdated
uint32_t current_sector_size = flash_get_sector_size(&_flash, addr); | ||
// addr and size should be aligned to page size, and multiple of page size | ||
// page program should not cross sector boundaries | ||
if ((is_aligned(addr, page_size) == false) || (is_aligned(size, page_size) == false) || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nitpick - this might be clearer if it is broken into individual checks.
if (!is_aligned(addr, page_size)) {
return -1;
}
if (!is_aligned(size, page_size)) {
return -1;
}
if (size < page_size) {
return -1;
}
if (is_crossing_sector(current_sector_size, addr, size)) {
return -1;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That actually looks more noisy to me. Maybe just one condition per line would help.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That actually looks more noisy to me. Maybe just one condition per line would help.
I'll do that.
drivers/FlashIAP.cpp
Outdated
int ret = 0; | ||
_mutex->lock(); | ||
if (flash_program_page(&_flash, addr, (const uint8_t *)buffer, size)) { | ||
return -1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to release lock before returing
drivers/FlashIAP.cpp
Outdated
// addr and size should be aligned to page size, and multiple of page size | ||
// page program should not cross sector boundaries | ||
if ((is_aligned(addr, page_size) == false) || (is_aligned(size, page_size) == false) || | ||
(size < page_size) || (((addr % current_sector_size) + size) > current_sector_size)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: Is sector size ever not a multiple of page size? The BlockDevice currently prohibits this, it could be an assert at construction time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, I dont think it can be not a multiple of page size.
drivers/FlashIAP.h
Outdated
* | ||
* @return Size of the underlying device in bytes | ||
*/ | ||
uint32_t get_flash_size() const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: How does the user find the beginning of flash?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be added later - flash regions properly defined and getters for them. Currently flash algo implementations define flash beginning as 0, but that is not correct (there can be app text/data).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plus having flash regions
697afbc
to
f767e96
Compare
Responded to comments, rebased, rerunning CI /morph test |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputBuild failed! |
f767e96
to
b28bf6b
Compare
/morph test |
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputTest failed! |
@c1728p9 If happy, please merge (the failure is for a platform that is not even supported on this branch, I'll investigate to fix it on master). Edit: I am goign to update this branch, master is green for the platform that fails here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me 👍
/morph test |
7a682aa
to
c627713
Compare
Added get_flash_start() method + all the functionality in HAL and tests updated |
c627713
to
74a5619
Compare
Result: FAILUREYour command has finished executing! Here's what you wrote!
OutputTest failed! |
edf7fb3
to
3ebcf92
Compare
74a5619
to
08730c1
Compare
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
3ebcf92
to
f258770
Compare
flash api should include this header file, as it contains required data declarations.
Flash IAP that provides write/read/program to an internal API. It invokes flash HAL functions. FlashIAP checks for alignments for erase/write/program. HAL functions do not, to avoid duplication per target implementation.
It currently tests functionality provided by flash IAP API like write/read/program/erase and getters.
Plus fixes in the tests to get properly end of flash (start + size)
08730c1
to
6f8fa63
Compare
/morph test |
Result: SUCCESSYour command has finished executing! Here's what you wrote!
OutputAll builds and test passed! |
Description
FlashIAP
class addition. It provides block device alike API (write/read/program) plus some getters that are useful for applications.I added a functional test that was tested with k64f, more to come.
Status
READY
This PR is for feature branch feature-flash-api
cc @c1728p9 @geky