-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
stm32: Refactor pyb.CAN implementation, add tests. #15989
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
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #15989 +/- ##
=======================================
Coverage 98.54% 98.54%
=======================================
Files 169 169
Lines 21877 21877
=======================================
Hits 21558 21558
Misses 319 319 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
c985e46
to
cbc443b
Compare
@iabdalkader @H-Grobben It's been a while, but this PR touches a bunch of driver code you've both worked on. Would appreciate any comments if you have the time. |
Code size report:
|
🤨 It seems very coincidental that this PR refactors so much code and ends up with exactly the same binary size... |
It's been years since I worked on FDCAN and CAN, so I don't remember much, but I'll try to take a look as soon as I have some free time. @kwagyeman is very interested in CAN support he might also want to take a look. |
@projectgus - I'll update my PR for CAN on the IMX after an API is approved and merged. |
Sounds great. Appreciate your patience with the CAN support, @kwagyeman. |
I didn't get time for a full review of this yet, but one thing I suggest is renaming the |
I can change this, but I wanted to check you're sure about it? From a usability perspective, it seems fiddly: Once other tests are added, it'd be necessary to run |
This comment was marked as outdated.
This comment was marked as outdated.
cbc443b
to
4ff44ce
Compare
4ff44ce
to
a9b9974
Compare
User modules can not access the 'pyb_can_obj_t' struct if it is defined in the pyb_can.c file. Is the struct also defined as a machine.CAN struct, in a .h file, which then be used by user modules? If it's put in the pyb_can.h file, it is still usable. I will try to review the code and run some tests on the can changes if I can find the time. -- update: need more time, but initial test locks up the micropython on the G4, with our custom c module, with this PR |
Thanks for taking a look, @H-Grobben.
Ah, sorry - I actually hadn't thought of the use case that a user C module might be using
Everything in I don't think any of the current
It wouldn't surprise me if there are other subtle behaviour changes that impact a custom C module calling into pyb module functions. If you figure out what's happening then I'm happy to try and tweak things to keep compatibility intact. |
@projectgus - Is CAN for the machine module ever going to be completed? Just providing a gentle push :) |
I know it's frustrating, I'm sorry it's dragging so long. I have not forgotten about it, but there's been a lot of other things to take care of as well. There has been some progress behind the scenes, hopefully will be visible in a PR draft soon. |
a9b9974
to
67cd5b6
Compare
@H-Grobben Have rebased this PR and moved the |
67cd5b6
to
a038b9b
Compare
(Rebased, no other changes.) |
I have run the tests from this PR on PYBV10+PYBV10 and PYBV10+PYBD_SF6 (so just standard CAN, not FDCAN). They pass before the refactoring in this PR and with this PR. Very good! I do like how the |
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've now done a full review of this PR. Apart from the above comments, it looks good.
6b72c1c
to
ea09d2f
Compare
@H-Grobben I've now noted two C API changes in the PR description above, it may help you debug your user C module. |
Marked as draft again as I need to add a bit more functionality to the lower layer for machine.CAN to work. |
Actually this is probably OK, can always do a second refactor PR if needed. |
uint16_t num_error_warning; | ||
uint16_t num_error_passive; | ||
uint16_t num_bus_off; |
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 necessary to count hardware errors?
It may be enough to perform bus recovering inside the driver.
See RM0008 Reference manual 24.7.6 Error management
See https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html#error-states-and-counters
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 is useful for the user to get an idea of if/when the bus is failing. They can access these "performance counters" via can.info()
.
(This is part of the Python API of pyb.CAN
, so can't really be changed.)
This is necessary for the machine.CAN implementation to use the same low-level functions. Includes some refactoring around FIFO selection as there was a footgun where CAN_FIFO0/1 are 0/1 but FDCAN_RX_FIFO0/1 are not. Added an explicit type for non-hardware-specific FIFO numbering. Also moved responsibility for re-enabling CAN receive interrupts into the higher layer (pyb_can.c layer) after calling can_receive(). Also includes this behaviour change for FDCAN boards: - Fix for boards with FDCAN not updating error status counters (num_error_warning, num_error_passive, num_bus_off). These are now updated the same as on boards with CAN Classic controllers, as documented. - Previously FDCAN boards would trigger the RX callback function on error events instead (passing undocumented irq numbers 3, 4, 5). This behaviour has been removed in favour of the documented behaviour of updating the status counters. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
Currently only classic CAN, but tests run on both the stm32 classic CAN controller and the FD-CAN controller with the same results. Signed-off-by: Angus Gratton <angus@redyak.com.au>
ea09d2f
to
dbda43b
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.
I retested on PYBV10+PYBV10. The new multitests still pass.
Summary
I've been gradually working on stm32 as the first implementation of the new CAN API (#12337), and first step was to refactor the low-level part of the
pyb.CAN
driver to be reusable frommachine.CAN
as well. In the course of doing this I also wrote some simple automated tests forpyb.CAN
.After doing the refactors and adding the tests I discovered some small bugs in various STM32 boards. This PR contains bugfix commits also submitted in #16543, #16545, #16546, #16547. Only the top two commits in this branch are unique to this PR (but it's difficult to run the tests without the other fixes).can.h API changes (only relevant for anyone writing C code against this API):
CAN_HandleTypeDef *
instead ofpyb_can_obj_t *
, to decouple the two layers.can_rx_fifo_t
enum for the RX FIFO selection. The numeric value of this enum is the same as the previous values used by bxCAN (0, 1), but they are different to the enums previously used by FDCAN. The FDCAN ST HAL enums are buffer offset values but these are now moved into the implementation and are no longer exposed in the API.can_receive()
. See pyb_can.c for the necessary code.As part of the refactoring some
pyb.CAN
behaviour changed on FDCAN, to make it the same as bxCAN:Testing
Ran the new multi-tests via command line:
Tests pass on various pairings of the following boards:
Trade-offs and Alternatives
pyb.CAN
driver and make the STM32machine.CAN
driver from scratch. Given how much refactoring was needed here then that does look like a somewhat appealing alternative in hindsight, especially as I'm not done yet! However, this way the code size will be smaller for as long as bothpyb.CAN
and the futuremachine.CAN
drivers are included in MicroPython.Follow-up work (not in this PR)