Skip to content

drivers: can: add Realtek Bee series support#105411

Open
YuzhuoLiuRTK wants to merge 3 commits into
zephyrproject-rtos:mainfrom
YuzhuoLiuRTK:upstream/drivers/can/add-driver
Open

drivers: can: add Realtek Bee series support#105411
YuzhuoLiuRTK wants to merge 3 commits into
zephyrproject-rtos:mainfrom
YuzhuoLiuRTK:upstream/drivers/can/add-driver

Conversation

@YuzhuoLiuRTK

@YuzhuoLiuRTK YuzhuoLiuRTK commented Mar 13, 2026

Copy link
Copy Markdown
Contributor

Important Note: This PR depends on hal_realtek repo PR for CAN lib(zephyrproject-rtos/hal_realtek#21).

Description

This PR adds the CAN driver support for Realtek Bee series SoCs. The driver is implemented based on the standard Zephyr CAN API and supports the following series:

  • RTL87x2G

Key features implemented:

  • Classic CAN 2.0B
  • Standard and Extended identifiers
  • Remote and data frames
  • Transmission and Reception

Testing

I have verified the driver functionality using the standard Zephyr CAN API test suite as well as a manual shell test with an external PHY and a CAN analyzer on the following hardware platform:

  1. Board: rtl87x2g_evb_a_rtl8762gku
    • SoC: RTL87X2G
    • CAN API Test: tests/drivers/can/api
    • Manual Test: CAN shell with external PHY and CAN Analyzer (verified TX, RX, and HW filtering)
    • Result: PASSED

Logs

CAN API Test Logs

------ TESTSUITE SUMMARY START ------

SUITE PASS - 100.00% [can_classic]: pass = 47, fail = 0, skip = 3, total = 50 duration = 1.056 seconds
 - PASS - [can_classic.test_add_filter] duration = 0.026 seconds
 - PASS - [can_classic.test_add_filter_without_callback] duration = 0.001 seconds
 - PASS - [can_classic.test_add_invalid_ext_filter] duration = 0.015 seconds
 - PASS - [can_classic.test_add_invalid_null_filter] duration = 0.001 seconds
 - PASS - [can_classic.test_add_invalid_std_filter] duration = 0.014 seconds
 - PASS - [can_classic.test_bitrate_limits] duration = 0.001 seconds
 - PASS - [can_classic.test_classic_get_capabilities] duration = 0.001 seconds
 - PASS - [can_classic.test_filters_added_while_stopped] duration = 0.019 seconds
 - PASS - [can_classic.test_filters_preserved_through_bitrate_change] duration = 0.031 seconds
 - PASS - [can_classic.test_filters_preserved_through_mode_change] duration = 0.031 seconds
 - PASS - [can_classic.test_get_core_clock] duration = 0.001 seconds
 - PASS - [can_classic.test_get_state] duration = 0.001 seconds
 - PASS - [can_classic.test_invalid_sample_point] duration = 0.001 seconds
 - PASS - [can_classic.test_max_ext_filters] duration = 0.049 seconds
 - PASS - [can_classic.test_max_std_filters] duration = 0.049 seconds
 - PASS - [can_classic.test_receive_timeout] duration = 0.105 seconds
 - PASS - [can_classic.test_recover] duration = 0.001 seconds
 - PASS - [can_classic.test_recover_while_stopped] duration = 0.001 seconds
 - SKIP - [can_classic.test_reject_ext_id_rtr] duration = 0.001 seconds
 - SKIP - [can_classic.test_reject_std_id_rtr] duration = 0.001 seconds
 - PASS - [can_classic.test_send_and_forget] duration = 0.014 seconds
 - PASS - [can_classic.test_send_callback] duration = 0.014 seconds
 - PASS - [can_classic.test_send_ext_id_dlc_of_range] duration = 0.010 seconds
 - PASS - [can_classic.test_send_ext_id_out_of_range] duration = 0.006 seconds
 - PASS - [can_classic.test_send_fd_format] duration = 0.012 seconds
 - PASS - [can_classic.test_send_invalid_dlc] duration = 0.010 seconds
 - PASS - [can_classic.test_send_null_frame] duration = 0.001 seconds
 - PASS - [can_classic.test_send_receive_ext_id] duration = 0.052 seconds
 - PASS - [can_classic.test_send_receive_ext_id_masked] duration = 0.116 seconds
 - PASS - [can_classic.test_send_receive_ext_id_rtr] duration = 0.031 seconds
 - PASS - [can_classic.test_send_receive_msgq] duration = 0.130 seconds
 - PASS - [can_classic.test_send_receive_std_id] duration = 0.052 seconds
 - PASS - [can_classic.test_send_receive_std_id_masked] duration = 0.051 seconds
 - PASS - [can_classic.test_send_receive_std_id_no_data] duration = 0.018 seconds
 - PASS - [can_classic.test_send_receive_std_id_rtr] duration = 0.031 seconds
 - PASS - [can_classic.test_send_receive_wrong_id] duration = 0.119 seconds
 - PASS - [can_classic.test_send_std_id_dlc_of_range] duration = 0.010 seconds
 - PASS - [can_classic.test_send_std_id_out_of_range] duration = 0.005 seconds
 - PASS - [can_classic.test_send_while_stopped] duration = 0.013 seconds
 - PASS - [can_classic.test_set_bitrate] duration = 0.001 seconds
 - PASS - [can_classic.test_set_bitrate_too_high] duration = 0.001 seconds
 - SKIP - [can_classic.test_set_bitrate_too_low] duration = 0.001 seconds
 - PASS - [can_classic.test_set_bitrate_while_started] duration = 0.001 seconds
 - PASS - [can_classic.test_set_mode_while_started] duration = 0.001 seconds
 - PASS - [can_classic.test_set_state_change_callback] duration = 0.001 seconds
 - PASS - [can_classic.test_set_timing_max] duration = 0.001 seconds
 - PASS - [can_classic.test_set_timing_min] duration = 0.001 seconds
 - PASS - [can_classic.test_set_timing_while_started] duration = 0.001 seconds
 - PASS - [can_classic.test_start_while_started] duration = 0.001 seconds
 - PASS - [can_classic.test_stop_while_stopped] duration = 0.001 seconds

SUITE SKIP -   0.00% [can_powermgmt]: pass = 0, fail = 0, skip = 3, total = 3 duration = 0.000 seconds
 - SKIP - [can_powermgmt.test_suspend_resume] duration = 0.000 seconds
 - SKIP - [can_powermgmt.test_suspend_while_filters_added] duration = 0.000 seconds
 - SKIP - [can_powermgmt.test_suspend_while_started] duration = 0.000 seconds

SUITE PASS - 100.00% [can_stats]: pass = 1, fail = 0, skip = 0, total = 1 duration = 0.001 seconds
 - PASS - [can_stats.test_can_stats_accessors] duration = 0.001 seconds

SUITE SKIP -   0.00% [can_transceiver]: pass = 0, fail = 0, skip = 1, total = 1 duration = 0.000 seconds
 - SKIP - [can_transceiver.test_get_transceiver] duration = 0.000 seconds

SUITE PASS - 100.00% [can_utilities]: pass = 3, fail = 0, skip = 0, total = 3 duration = 0.003 seconds
 - PASS - [can_utilities.test_can_bytes_to_dlc] duration = 0.001 seconds
 - PASS - [can_utilities.test_can_dlc_to_bytes] duration = 0.001 seconds
 - PASS - [can_utilities.test_can_frame_matches_filter] duration = 0.001 seconds

------ TESTSUITE SUMMARY END ------

===================================================================
PROJECT EXECUTION SUCCESSFUL

Shell Test Logs

uart:~$ can start can@40038000
starting can@40038000
uart:~$ can send can@40038000 0x123 1 2 3 4 5 6 7 8
enqueuing CAN frame #0 with standard (11-bit) CAN ID 0x123, RTR 0, CAN FD 0, BRS 0, DLC 8
CAN frame #0 successfully sent
uart:~$ can send can@40038000 0x123 1 2 3 4 5 6 7 8
enqueuing CAN frame #1 with standard (11-bit) CAN ID 0x123, RTR 0, CAN FD 0, BRS 0, DLC 8
CAN frame #1 successfully sent
uart:~$ can send can@40038000 0x123 1 2 3 4 5 6 7 8
enqueuing CAN frame #2 with standard (11-bit) CAN ID 0x123, RTR 0, CAN FD 0, BRS 0, DLC 8
CAN frame #2 successfully sent
uart:~$ can filter add can@40038000 0x1
adding filter with standard (11-bit) CAN ID 0x001, CAN ID mask 0x7ff
filter ID: 0
uart:~$ can filter add can@40038000 -e 0x2
adding filter with extended (29-bit) CAN ID 0x00000002, CAN ID mask 0x1fffffff
filter ID: 1
can@40038000       001   [8]  01 23 45 67 89 ab cd ef
can@40038000       001   [8]  remote transmission request
can@40038000  00000002   [8]  01 23 45 67 89 ab cd ef
can@40038000  00000002   [8]  remote transmission request
uart:~$ can filter remove can@40038000 0
removing filter with ID 0
uart:~$ can filter remove can@40038000 1
removing filter with ID 1
uart:~$ can stop can@40038000
stopping can@40038000

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch 2 times, most recently from d124069 to aba1b77 Compare March 17, 2026 07:10
@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from aba1b77 to ab33cff Compare March 24, 2026 04:02
@github-actions

github-actions Bot commented Mar 24, 2026

Copy link
Copy Markdown

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
hal_realtek zephyrproject-rtos/hal_realtek@b106aa7 (main) zephyrproject-rtos/hal_realtek#21 zephyrproject-rtos/hal_realtek#21/files

Additional metadata changed:

Name URL Submodules West cmds module.yml Blobs
hal_realtek 3x 🆕

DNM label due to: 1 project with PR revision, 1 project with metadata changes and 3 blob changes

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions Bot added manifest manifest-hal_realtek DNM (manifest) This PR should not be merged (controlled by action-manifest) Binary Blobs Added labels Mar 24, 2026
@sonarqubecloud

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

This pull request has been marked as stale because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 7 days. Note, that you can always re-open a closed pull request at any time.

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch 2 times, most recently from 481f5af to 5e06cb1 Compare May 18, 2026 07:34
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hello, @henrikbrixandersen if you have some time, I’d really appreciate it if you could review this PR. Thanks!

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from 5e06cb1 to a2f8097 Compare May 26, 2026 02:45
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Rebased to resolve conflicts.

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from a2f8097 to 286b4f4 Compare June 2, 2026 03:20

@henrikbrixandersen henrikbrixandersen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from 286b4f4 to d4d2104 Compare June 3, 2026 08:46
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hi @henrikbrixandersen

Added. Please continue the review, and feel free to let me know if any further changes are needed. Thanks!

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from d4d2104 to 683a046 Compare June 10, 2026 05:44
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Rebased to resolve conflicts.

@sonarqubecloud

Copy link
Copy Markdown

@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hi, @henrikbrixandersen Sorry to ping you again. This PR has been open for a while. If you have time, could you please continue reviewing this PR? Thanks!

@henrikbrixandersen

Copy link
Copy Markdown
Member

Hi, @henrikbrixandersen Sorry to ping you again. This PR has been open for a while. If you have time, could you please continue reviewing this PR? Thanks!

Hi, yes - my apologies for the delay. I have set aside time for reviewing this and a bunch of other CAN driver additions early next week.

@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hi, @henrikbrixandersen Sorry to ping you again. This PR has been open for a while. If you have time, could you please continue reviewing this PR? Thanks!

Hi, yes - my apologies for the delay. I have set aside time for reviewing this and a bunch of other CAN driver additions early next week.

No worries at all. Thanks a lot for the update.
I appreciate your help and look forward to your feedback. :)

Comment thread drivers/can/Kconfig.bee Outdated
default y
depends on DT_HAS_REALTEK_BEE_CAN_ENABLED
select HAL_REALTEK_BEE_CAN
select CAN_ACCEPT_RTR

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should not be selected by the driver. It should be selected by the application if needed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed, thanks~

Comment thread drivers/can/Kconfig.bee Outdated
Comment on lines +39 to +63
config CAN_BEE_MAX_STD_ID_FILTER
int "Maximum number of standard (11-bit) ID filters"
default 5
range 0 CAN_BEE_RX_MSG_BUF_NUM
help
Defines the maximum number of filters with standard ID (11-bit)
that can be added by the application.
The tx and rx share 16 message buffers in total.
Each rx message buffer can filter one standard or extended ID.
The following equation determines the maximum total number of
filters:
CAN_BEE_MAX_STD_ID_FILTER + CAN_BEE_MAX_EXT_ID_FILTER <= CAN_BEE_RX_MSG_BUF_NUM

config CAN_BEE_MAX_EXT_ID_FILTER
int "Maximum number of extended (29-bit) ID filters"
default 5
range 0 CAN_BEE_RX_MSG_BUF_NUM
help
Defines the maximum number of filters with extended ID (29-bit)
that can be added by the application.
The tx and rx share 16 message buffers in total.
Each rx message buffer can filter one standard or extended ID.
The following equation determines the maximum total number of
filters:
CAN_BEE_MAX_STD_ID_FILTER + CAN_BEE_MAX_EXT_ID_FILTER <= CAN_BEE_RX_MSG_BUF_NUM

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are these two really needed? Isn't CONFIG_CAN_BEE_RX_MSG_BUF_NUM sufficient?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is indeed redundant and has been removed. Thanks~

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Perhaps name this can_realtek_bee.c instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Renamed, thanks!

Comment thread dts/arm/realtek/bee/rtl87x2g.dtsi Outdated
Comment on lines +586 to +587
bitrate = <500000>;
sample-point = <875>;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These should not be set in the DTSI. Instead, rely on the defaults set via Kconfig.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah I noticed the CONFIG_CAN_DEFAULT_BITRATE in Kconfig. Removed here, thanks!

Comment thread dts/bindings/can/realtek,bee-can.yaml Outdated
description: |
Prescaler value for computing the rx timestamps of received messages.
The timestamp counter is derived from the CAN source clock divided by this value.
Valid range is [1, 256].

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please use min and max for this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated, thanks~

Comment thread drivers/can/can_bee.c Outdated
return 0;

fail:
LOG_ERR("CAN send failed: %d", ret);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You just logged the reason above.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed the redundant log here, thanks~

}
}

static int can_bee_start(const struct device *dev)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You need to reset the CAN statistics here. Check the other drivers for inspiration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added, thanks~

Comment thread drivers/can/can_bee.c Outdated
{
ARG_UNUSED(dev);

if (SET == CAN_GetErrorStatus(CAN_ERROR_ACK)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Where is SET declared?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

typedef enum
{
    RESET = 0,
    SET = !RESET
} FlagStatus, ITStatus;

SET is defined as 1 in the HAL. In practice, true / false can also meet the requirement.

return 0;
}

static DEVICE_API(can, can_bee_driver_api) = {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

How does this core handle CAN bus recovery?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since the bus on/off state of this CAN controller depends on the external PHY device, manual recovery is not supported.

Comment thread drivers/can/can_bee.c Outdated
.clkid = DT_INST_CLOCKS_CELL(index, id), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
.irq_config_func = config_can_##index##_irq, \
.rx_timestamp_prescaler = DT_INST_PROP(index, rx_timestamp_prescaler), \

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You could opt to use DT_INST_PROP_OR() here and remove the default in the binding.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah I use DT_INST_PROP_OR to set the default value and removed in the binding file. Thanks!

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch 2 times, most recently from 9fefab6 to b28cfb1 Compare July 6, 2026 05:38
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hi, @henrikbrixandersen , since the SOC does not directly bind the CAN function to specific pins, users can pinmux CAN to any pins. Therefore, we did not directly enable CAN bus or specify its pins in the board DTS. This causes the CI for the “build all tests” check to fail, so I removed CAN from the board supported feature list.

@henrikbrixandersen

Copy link
Copy Markdown
Member

Hi, @henrikbrixandersen , since the SOC does not directly bind the CAN function to specific pins, users can pinmux CAN to any pins. Therefore, we did not directly enable CAN bus or specify its pins in the board DTS. This causes the CI for the “build all tests” check to fail, so I removed CAN from the board supported feature list.

This needs to be integrated and build on at least one board in the tree.

@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hi, @henrikbrixandersen , since the SOC does not directly bind the CAN function to specific pins, users can pinmux CAN to any pins. Therefore, we did not directly enable CAN bus or specify its pins in the board DTS. This causes the CI for the “build all tests” check to fail, so I removed CAN from the board supported feature list.

This needs to be integrated and build on at least one board in the tree.

Okay, I will add CAN on one board, thanks!

@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from b28cfb1 to 0d465d5 Compare July 6, 2026 07:48
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Hi, @henrikbrixandersen , I have updated the code and tested locally. The CI alse passed. Could you please take another look when you have time? Thanks!

Update hal realtek drivers and add ADC/CAN driver support.

Signed-off-by: Yuzhuo Liu <yuzhuo_liu@realsil.com.cn>
Add CAN driver support for Realtek Bee series SoCs,
including RTL87x2G.

This driver supports:
- Classic CAN 2.0A/B
- Standard and Extended identifiers
- Remote and data frames
- Transmission and Reception

Signed-off-by: Yuzhuo Liu <yuzhuo_liu@realsil.com.cn>
Add build-only test for Realtek Bee CAN controller in the tree.

Signed-off-by: Yuzhuo Liu <yuzhuo_liu@realsil.com.cn>
@YuzhuoLiuRTK YuzhuoLiuRTK force-pushed the upstream/drivers/can/add-driver branch from 0d465d5 to 7f6404b Compare July 9, 2026 09:52
@YuzhuoLiuRTK

Copy link
Copy Markdown
Contributor Author

Rebased to resolce conflicts.

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Boards/SoCs area: CAN area: Devicetree Binding PR modifies or adds a Device Tree binding area: Tests Issues related to a particular existing or missing test Binary Blobs Added DNM (manifest) This PR should not be merged (controlled by action-manifest) manifest manifest-hal_realtek platform: Realtek Bee Realtek Bee series platform: Realtek

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants