-
Notifications
You must be signed in to change notification settings - Fork 6
Add I2C device emulation support for ARM targets #4
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
This commit adds emulation of the magnetometer on the LSM303DLHC. It allows the magnetometer's X, Y and Z outputs to be set via the mag-x, mag-y and mag-z properties, as well as the 12-bit temperature output via the temperature property. Sensor can be enabled with 'CONFIG_LSM303DLHC_MAG=y'. Signed-off-by: Kevin Townsend <kevin.townsend@linaro.org> Message-id: 20220130095032.35392-1-kevin.townsend@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org> (cherry picked from commit 4fd1ebb)
Currently there is no way for a board model's Kconfig stanza to say "I have an i2c bus which the user can plug an i2c device into, build all the free-standing i2c devices". The Kconfig mechanism for this is the "device group". Add an I2C_DEVICES group along the same lines as the existing PCI_DEVICES. Simple free-standing i2c devices which a user might plausibly want to be able to plug in on the QEMU commandline should have default y if I2C_DEVICES and board models which have an i2c bus that is user-accessible should use imply I2C_DEVICES to cause those pluggable devices to be built. In this commit we mark only a fairly conservative set of i2c devices as belonging to the I2C_DEVICES group: the simple sensors and RTCs (not including PMBus devices or devices which need GPIO lines to be connected). Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Hao Wu <wuhaotsh@google.com> Message-id: 20220208155911.3408455-2-peter.maydell@linaro.org (cherry picked from commit b5bf5a5)
For arm boards with an i2c bus which a user could reasonably want to plug arbitrary devices, add 'imply I2C_DEVICES' to the Kconfig stanza. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Acked-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Reviewed-by: Hao Wu <wuhaotsh@google.com> Message-id: 20220208155911.3408455-3-peter.maydell@linaro.org (cherry picked from commit e117e97)
|
Thanks @stephanosio For reference sake, this sensor can added to QEMU at startup via: $ qemu-system-arm -M mps2-an521 -device loader,file=build/zephyr/zephyr.elf -serial stdio \
-monitor tcp:localhost:4444,server,nowait \
-device lsm303dlhc_mag,id=lsm303,address=0x1EWe can be automatically handles this in Zephyr with an addition like this to the project cmake file: For the device tree (mps2_an521 or mps3_an547 assumed here): Config settings: |
|
To update values for the magn or temp sensor, you have a several options, but the easiest to quickly test is with the monitor interface (see $ nc localhost 4444
QEMU 6.0.93 monitor - type 'help' for more information
(qemu) qom-list /machine/peripheral/
(qemu) qom-set lsm303 mag-x 1000
(qemu) qom-set lsm303 temperature 23000Note: For the magnetometer 1 = 0.001 uT, and for the temperature sensor 1 = 0.001 C |
|
Thanks, very exciting |
|
It's nice to have emulated devices that appear exactly the same as real HW on the I2C bus. This should make testing specific edge cases with sensors much easier, although you'll need something to script the sensor data updates in parallel. Most languages have libraries to make communicting with QEMU possible, though, and it can be done in a bash script in a pinch. I only emulate the magnetometer for now since it was a much simpler device than the accel (less than a dozen registers), but it's still useful as a proof of concept. |
|
@avisconti FYI |
|
This seems OK: $ ./qemu-system-arm -device help | grep lsm
name "lsm303dlhc_mag", bus i2c-bus$ ./qemu-system-arm -M mps2-an521 -S -monitor stdio \
-device lsm303dlhc_mag,id=lsm303,address=0x1E
QEMU 6.2.0 monitor - type 'help' for more information
(qemu) VNC server running on ::1:5900
(qemu) qom-list /machine/peripheral
type (string)
lsm303 (child<lsm303dlhc_mag>)
(qemu) qom-get lsm303 temperature
0
(qemu) qom-set lsm303 temperature 23000
(qemu) qom-get lsm303 temperature
23000After adding the DTS overlay and kconfig changes mentionned earlier in this PR, I built an image with: $ west build -p -b mps2_an521 zephyr/samples/sensor/sensor_shell/Then run it with: $ ./qemu-system-arm -M mps2-an521 \
-device loader,file=/home/ubuntu/zephyr/build/zephyr/zephyr.elf \
-serial stdio -monitor tcp:localhost:4444,server,nowait \
-device lsm303dlhc_mag,id=lsm303,address=0x1E
VNC server running on ::1:5900
uart:~$ i2c scan I2C_SHIELD1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
1 devices found on I2C_SHIELD1
uart:~$ sensor get LSM303DLHC-MAGN magn_xyz
channel idx=11 magn_xyz x = 0.000000 y = 0.000000 z = 0.000000Update the register values via QOM in the qemu terminal: $ nc localhost 4444
(qemu) qom-list /machine/peripheral/lsm303
qom-list /machine/peripheral/lsm303
type (string)
parent_bus (link<bus>)
realized (bool)
hotplugged (bool)
hotpluggable (bool)
address (uint8)
mag-y (int)
temperature (int)
mag-z (int)
mag-x (int)
(qemu) qom-set lsm303 mag-x 1000
qom-set lsm303 mag-x 1000
(qemu) qom-set lsm303 mag-z 1500
qom-set lsm303 mag-z 1500Then scan the device again in zephyr's shell: uart:~$ sensor get LSM303DLHC-MAGN magn_xyz
channel idx=11 magn_xyz x = 0.010000 y = 0.000000 z = 0.014285Note that the z value doesn't exactly match the expected 0.015 since it will scale inputs to the closest valid value based on the magnetometer gain, etc. |
ASAN detected a leak when running the ahci-test
/ahci/io/dma/lba28/retry:
Direct leak of 35 byte(s) in 1 object(s) allocated from:
#0 in malloc
#1 in __vasprintf_internal
#2 in vasprintf
#3 in g_vasprintf
#4 in g_strdup_vprintf
#5 in g_strdup_printf
#6 in object_get_canonical_path ../qom/object.c:2096:19
#7 in blk_get_attached_dev_id_or_path ../block/block-backend.c:1033:12
#8 in blk_get_attached_dev_path ../block/block-backend.c:1047:12
#9 in send_qmp_error_event ../block/block-backend.c:2140:36
#10 in blk_error_action ../block/block-backend.c:2172:9
#11 in ide_handle_rw_error ../hw/ide/core.c:875:5
#12 in ide_dma_cb ../hw/ide/core.c:894:13
qemu#13 in dma_complete ../system/dma-helpers.c:107:9
qemu#14 in dma_blk_cb ../system/dma-helpers.c:129:9
qemu#15 in blk_aio_complete ../block/block-backend.c:1552:9
qemu#16 in blk_aio_write_entry ../block/block-backend.c:1619:5
qemu#17 in coroutine_trampoline ../util/coroutine-ucontext.c:175:9
Plug the leak by freeing the device path string.
Signed-off-by: Fabiano Rosas <farosas@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20241111145214.8261-1-farosas@suse.de>
[PMD: Use g_autofree]
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-ID: <20241111170333.43833-3-philmd@linaro.org>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
(cherry picked from commit 23ea425)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Cherry-pick upstream patches to support I2C device emulation (e.g. LSM303DLHC magnetometer) for ARM targets
Zephyr SDK PR: zephyrproject-rtos/sdk-ng#449