Skip to content

add watchdog timer for mspm0 i2c driver #44

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

Closed
wants to merge 3 commits into from

Conversation

dkarnikis
Copy link

check individual commits:

Example of an i2c call where the slave spends too much time in the i2c callback and the watchdog timer (in the slave) reset the i2c lines and the mcu

image

@dkarnikis dkarnikis requested review from tbursztyka, sipraga and a team March 26, 2025 12:26
@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from 639cc23 to f82d96e Compare March 26, 2025 12:30
@dkarnikis
Copy link
Author

Concerns:

  1. what do we do when one of the timer call fails
  2. i had to change the driver priority from I2C_INIT_PRIOTITY to COUNTER_INIT_PRIORITY

Copy link

@tbursztyka tbursztyka left a comment

Choose a reason for hiding this comment

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

As there is no watchdog driver for mspm0 in beo/3.5.99, there is only the counter you can use.
But when moving to beo/4.1.0 are you planning to move to watchdog api? (ti has provided a watchdog driver, no idea how well it works though). If not, then it will require to detail that you need a counter phandle, or else once running it will just crash.

About disabling coredump, it is because the default backend is the "logging" one which indeed takes too much cpu etc... Perhaps detail that in the commit message. (we will switch to in-memory backend when relevant)

@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from f82d96e to ab940d6 Compare March 26, 2025 14:13
@dkarnikis
Copy link
Author

dkarnikis commented Mar 26, 2025

As there is no watchdog driver for mspm0 in beo/3.5.99, there is only the counter you can use. But when moving to beo/4.1.0 are you planning to move to watchdog api? (ti has provided a watchdog driver, no idea how well it works though). If not, then it will require to detail that you need a counter phandle, or else once running it will just crash.

I think I also saw the driver from ti, but wasn't for mspm0.
This pr is more of a proof of concept / starting point for us to start modeling the whole idea. Of course the counter driver is not the best approach, for it seems for now that it does the job (until we get a watchdog in place).
Worst case scenario, I write the driver from scratch.

About disabling coredump, it is because the default backend is the "logging" one which indeed takes too much cpu etc... Perhaps detail that in the commit message. (we will switch to in-memory backend when relevant)

Will do!

@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch 2 times, most recently from ec1081b to a7efd36 Compare March 26, 2025 14:30
@tbursztyka
Copy link

This pr is more of a proof of concept / starting point for us to start modeling the whole idea. Of course the counter driver is not the best approach, for it seems for now that it does the job (until we get a watchdog in place).
Worst case scenario, I write the driver from scratch.

Once this PR merged, I will add it to beo/4.1.0 so we could try the mspm0 watchdog driver there

@dkarnikis dkarnikis requested a review from Svendsen991 March 27, 2025 10:31
@tbursztyka tbursztyka self-requested a review March 27, 2025 11:14
tbursztyka
tbursztyka previously approved these changes Mar 27, 2025
@@ -903,7 +982,7 @@ static const struct i2c_driver_api i2c_mspm0g3xxx_driver_api = {
\
I2C_DEVICE_DT_INST_DEFINE(index, i2c_mspm0g3xxx_init, NULL, &i2c_mspm0g3xxx_data_##index, \
&i2c_mspm0g3xxx_cfg_##index, POST_KERNEL, \
CONFIG_I2C_INIT_PRIORITY, &i2c_mspm0g3xxx_driver_api); \
CONFIG_COUNTER_INIT_PRIORITY, &i2c_mspm0g3xxx_driver_api); \
Copy link
Author

Choose a reason for hiding this comment

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

@tbursztyka do you think this change will cause an issue?

Choose a reason for hiding this comment

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

No you do need i2c to start after counter, as it uses the counter device at init phase. But indeed I think this change is not the "right one", I mean: there is a cleaner way to do it.

Just a sec, don't merge yet

Copy link

@tbursztyka tbursztyka Apr 2, 2025

Choose a reason for hiding this comment

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

Better add a Kconfig.mspm0 option called config I2C_MSPM0G3XXX_INIT_PRIORITY and set it to COUNTER_INIT_PRIORITY by default. And above use CONFIG_I2C_MSPM0G3XXX_INIT_PRIORITY

When building, the final priority is made of such hardcoded value and one computed though DTS dependency tree.
In the final zephyr.map file you'll find something like:

 .z_init_POST_KERNEL50_00066_
                0x000000000000fab0        0x8 zephyr/drivers/i2c/libdrivers__i2c.a(i2c_mspm0.c.obj)
 .z_init_POST_KERNEL60_00050_
                0x000000000000fab8        0x8 zephyr/libzephyr.a(emul_pca954x.c.obj)

See the 50_xxxxx_ or 60_xxxxx_ the first number is the hard-coded one, and the second the one coming from DTS.
It's actually a strip on a wooden-leg: without the proper change on the hardcoded value that you did, even if DTS knows the dependency of i2c to the counter: the final priority would be wrong anyway. (counter has a default value of 60...)

Thus why I tried to fix it (never got to finish it, and selling it damn hard because zephyr way of getting changes in...) zephyrproject-rtos#79340 which would generate a unique number of priority without any hard coded value anywhere. Just a damn dependency tree which is the only right way.

Copy link
Author

@dkarnikis dkarnikis Apr 2, 2025

Choose a reason for hiding this comment

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

that's a lot of files changed here! but i definitely see your point.

The priority issue should be fixed in the latest commits

Choose a reason for hiding this comment

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

that's a lot of files changed here! but i definitely see your point.

reg-exp changing all the device instantiation macros , hopefully nothing done by hand. I should get back to it when I'll have time, only 2 tests were failing due to one external patch I was waiting for...

@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from a7efd36 to cbfa554 Compare April 2, 2025 07:16
@dkarnikis
Copy link
Author

@tbursztyka the last commit fixes a commit message typo

@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from 298ff16 to 64d9f2f Compare April 2, 2025 10:50
@dkarnikis dkarnikis requested a review from tbursztyka April 2, 2025 11:04
add properties to configure the I2C watchdog reset timeout and and
panic error code. Also, add a new kconfig property to define the driver
init priority. Since the i2c driver has a dependency to the counter
driver, we need to adjust for that.

Signed-off-by: Dimitris Karnikis <dika@bang-olufsen.dk>
@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from 64d9f2f to b6bb7c2 Compare April 2, 2025 11:28
@dkarnikis
Copy link
Author

@sipraga kind reminder :)

data->target_rx_valid =
tconfig->callbacks->write_requested(tconfig);
i2c_mspm0g3xxx_target_stop_watchdog(data);

Choose a reason for hiding this comment

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

I'm not sure that this is correct? You essentially want to start the watchdog when a transaction starts, this is good as is. But you only want to stop the watchdog once the ACKOverride is getting set (then we can debate whether to stop the watchdog before or after that)

@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from ac16f03 to 7c6d1ac Compare April 14, 2025 06:53
@dkarnikis
Copy link
Author

The changes were checked against i2c reads/writes, and the driver always managed to recover

describe the watchdog timer property that will reset the mcu and the
i2c lines (to high) to avoid potential SCL stuck low issues

Signed-off-by: Dimitris Karnikis <dika@bang-olufsen.dk>
When the system is crashing, the I2C lines (SDA/SCL) are not being
reset and might stay LOW. To address this issue, we need to ensure that
none of the user i2c driver callbacks (that are doing reads or writes)
are taking longer than CONFIG_I2C_MSPM0G3XXX_WATCHDOG_TIMEOUT. So we
fire a timer before each call. If the callback doesn't finish fast
enough, the watchdog callback will reset the i2c lines, NACK the i2c
message and panic with the CONFIG_MSPM0G3XXX_I2C_WATCHDOG_PANIC_CODE
error code.

The timeout is configured with CONFIG_I2C_MSPM0G3XXX_WATCHDOG_TIMEOUT
The panic error code is configured with
CONFIG_MSPM0G3XXX_I2C_WATCHDOG_PANIC_CODE.

To make use of this reboot feature, the device tree needs to provide
a reference to a hardware timer. Let's say we want to use timer timg7
as a watchdog:

We need to configure that timer in the dts:

```
&timg7 {
	status = "okay";
	mode = <ONE_SHOT_DOWN>;
	prescaler = <0>;
	divide-ratio = <RATE_1>;
};
```

and then reference in the i2c block:

```
&i2c0 {
	watchdog-timer = <&timg7>;
	extras ...
```

Since we are invoking a software panic on the mcu, make sure to disable
the COREDUMP since the default backend is the "logging" one and it takes
too much of the cpu resources, thus delaying the mcu reboot.

This can be done with:
```
CONFIG_DEBUG_COREDUMP=n
```

Of course for now, the implementation is using a counter timer since
we don't have a mspm0 watchdog.

We need to also use I2C_MSPM0G3XXX_INIT_PRIORITY as the driver init
priority.

Signed-off-by: Dimitris Karnikis <dika@bang-olufsen.dk>
@dkarnikis dkarnikis force-pushed the dika/a2b-i2c-watchdog branch from 7c6d1ac to 9c273d7 Compare April 14, 2025 08:40
@dkarnikis
Copy link
Author

Closed in favor of: #45
so I don't have to rebase the whole mess

@dkarnikis dkarnikis closed this Apr 14, 2025
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.

3 participants