-
Notifications
You must be signed in to change notification settings - Fork 3k
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
CAN: Use uintptr_t for can_irq_ids #15077
Conversation
@hazzlim, thank you for your changes. |
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 curiosity what target are you using?
Most mbed os targets being cortex-m their pointer size if 32bits.
hal/include/hal/can_api.h
Outdated
@@ -63,7 +63,7 @@ typedef struct { | |||
int td_function; | |||
} can_pinmap_t; | |||
|
|||
typedef void (*can_irq_handler)(uint32_t id, CanIrqType type); | |||
typedef void (*can_irq_handler)(uintptr_t id, CanIrqType type); |
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 carries the additional meaning that the id is a pointer. size_t
may be more appropriate (and passing in the index in the table rather than a pointer).
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.
My understanding of how the drivers CAN Class and the HAL can_api interoperate is that the CAN constructor passes the address of itself cast to an integer type via can_irq_init
, which becomes the id in the table. CAN has a static method _irq_handler
which takes the id/address and then casts it back to a CAN *
in order to call the correct callbacks.
As this _irq_handler
method is what the can_irq_handler
type is used to refer to in all the can_api
implementations, I was intentionally using a pointer type because the id is indeed a pointer - it's pointers all the way down if you will. The id
here is not an index into the table, it's the value from the table. But maybe I am peeling back the curtain too much here and size_t
would still be more appropriate for the api?
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 had a deeper look at a few hal impl and as far as I can see the ID is never used in the lowlevel driver, it is only passed back to the callbacks.
The fact that this ID is a pointer instead of an plain integer is a shortcut that the Driver takes in the definition/management of IDs. By changing the type of the HAL here we are bending the definition of ID from the HAL to accommodate the hacky thing the Driver does (casting its this
to something not guaranteed to be able to hold its value).
Other HAL have similar needs and some made the choice to make it an intptr_t
with the nuance that it's not called an ID but a context. (id also to some extend imply unicity which is not even required by the driver itself).
So if we intend to keep the pointer shortcut (which makes sense for efficiency), I recommand we use "context" rather than "id". This way we have a clear "pointer to the context related to that callback" rather than "and Id that happen to also be a pointer so we changed its type to make sure it cal hold that pointer's value".
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 makes sense - I'll amend with this naming change, for greater clarity. Is there a preference between intptr_t
and uintptr_t
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.
No strong preference for me. If sign does not add value (e.g. as in the distance between two pointers) I'd probably use the unsigned version but if someone thinks otherwise I'm ok with either.
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.
So if we intend to keep the pointer shortcut (which makes sense for efficiency), I recommand we use "context" rather than "id". This way we have a clear "pointer to the context related to that callback" rather than "and Id that happen to also be a pointer so we changed its type to make sure it cal hold that pointer's value".
Revisiting, this makes even more sense - code currently uses id
to refer to both the context itself and the index into the array used to select the context. Now we have a clear distinction.
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.
Rebased with naming changes :)
Sorry, I hoped it was clear - the change is in order to allow building of CAN API on host machines for Unit Testing, which is currently not possible! |
The HAL can_api stores an array of IDs in order to dispatch interrupts to the correct CAN object. The drivers level CAN Class casts a pointer to itself to an uint32_t, which is stored as the ID and then cast back to a CAN * in order to call the correct handler. This results in compilation failure when the size of an object pointer is greater than uint32_t, for example when building on a PC for unit testing. In order to allow Unit Testing of the CAN Class, we replace the use of uint32_t with uintptr_t (type capable of holding a pointer), which allows portability and expresses intentions more clearly. In aid of this latter goal, we also replace the use of the name "id" with "context", to improve clarity. These are addresses of the context related to that callback.
55ee54f
to
b493a15
Compare
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.
LGTM
This pull request has automatically been marked as stale because it has had no recent activity. @ARMmbed/mbed-os-maintainers, please complete review of the changes to move the PR forward. Thank you for your contributions. |
CI started |
Jenkins CI Test : ✔️ SUCCESSBuild Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & ArtifactsCLICK for Detailed Summary
|
Summary of changes
This pull-request is a proposed solution to this problem, for discussion, which can then be applied to other Drivers APIs which exhibit similar barriers to compilation for unit testing (e.g. similar changes required for
gpio_irq_api
).Impact of changes
Migration actions required
Documentation
Pull request type
Test results
Reviewers
@ARMmbed/mbed-os-core @ARMmbed/mbed-os-hal