I2C 8 位元位址記憶體目標¶
PxI2C8BitAddressMemoryTarget 在 I2C(或 I3C)匯流排上模擬位元組定址記憶體裝置。控制器以 7 位元 I2C 位址 加上 8 位元記憶體偏移(子位址)存取裝置,再讀寫連續位元組區塊。
當你要測試控制器驅動程式、EEPROM 風格週邊,或以線性記憶體陣列而非固定 32 位元暫存器配置作為後端的暫存器檔時,這個目標很有用。
記憶體模型¶
- 256 位元組 後端儲存(
0x00–0xFF)。 - 建立時設定的 靜態 I2C 位址(例如
0x50)。 - 8 位元子位址 作為寫入交易的第一個資料位元組送出,或在帶子位址的讀取序列之前寫入。
匯流排上典型寫入如下:
典型帶子位址讀取如下:
Exerciser 在匯流排傳輸期間直接更新後端記憶體。Python 可透過 read_mem / write_mem 檢視或預載記憶體,不必經過 I2C 控制器。
快速開始¶
將目標掛載到 I2C 匯流排,並從 Python 讀寫記憶體:
from aqpxlib import AqProtocolExerciser
from aqpxlib.i2c import PxI2CBus, PxI2C8BitAddressMemoryTarget
with AqProtocolExerciser.connect(port=60600) as px:
i2c_bus = PxI2CBus(px, scl=0, sda=1)
target = PxI2C8BitAddressMemoryTarget(px, address=0x50)
target.attach_to_bus(i2c_bus)
target.write_mem(0x10, [0x01, 0x02, 0x03, 0x04])
assert target.read_mem(0x10, 4) == [0x01, 0x02, 0x03, 0x04]
target.detach_from_bus()
控制器存取¶
在同一條匯流排上使用 PxI2CController,以真實控制器的方式操作目標:
from aqpxlib import AqProtocolExerciser
from aqpxlib.i2c import PxI2CBus, PxI2CController, PxI2C8BitAddressMemoryTarget
with AqProtocolExerciser.connect(port=60600) as px:
i2c_bus = PxI2CBus(px, scl=0, sda=1)
target = PxI2C8BitAddressMemoryTarget(px, address=0x50)
target.attach_to_bus(i2c_bus)
i2c_controller = PxI2CController(px)
i2c_controller.attach_to_bus(i2c_bus)
sub_address = 8
data = [0xDE, 0xAD, 0xBE, 0xEF]
i2c_controller.i2c_write_addr(target.address, sub_address, data)
read_back = i2c_controller.i2c_read_addr(target.address, sub_address, len(data))
assert read_back == data
# 確認後端儲存與控制器寫入的內容一致.
assert target.read_mem(sub_address, len(data)) == data
i2c_controller.detach_from_bus()
target.detach_from_bus()
匯流排存取事件¶
當匯流排上其他裝置讀寫此目標時,exerciser 會在目標實例上發出 memory_target_write_event 與 memory_target_read_event。這些是共用事件型別(I3C、SPI 等其他記憶體目標也使用):
| 事件 | Payload 欄位 | 發出時機 |
|---|---|---|
memory_target_write_event |
addr, data |
匯流排寫入傳輸完成後 |
memory_target_read_event |
addr, count |
匯流排讀取傳輸完成後 |
為每種事件型別分別訂閱處理函式:
from aqpxlib.event import PxMemoryTargetReadEvent, PxMemoryTargetWriteEvent
@target.on_event(PxMemoryTargetWriteEvent)
def on_memory_target_write(write: PxMemoryTargetWriteEvent):
print(f"Bus write @ 0x{write.addr:02x}: {write.data.hex()}")
@target.on_event(PxMemoryTargetReadEvent)
def on_memory_target_read(read: PxMemoryTargetReadEvent):
print(f"Bus read @ 0x{read.addr:02x}, {read.count} bytes")
事件只反映匯流排活動。從 Python 呼叫 read_mem / write_mem 不會發出記憶體目標事件。
另見: 事件註冊與處理函式設定。
I3C 匯流排支援¶
PxI2C8BitAddressMemoryTarget 可掛載到 I3C 匯流排(valid_buses 包含 "i3c" 與 "i2c")。裝置在 I3C SDA 線上以 I2C 風格目標運作。
API 參考¶
PxI2C8BitAddressMemoryTarget
¶
PxI2C8BitAddressMemoryTarget(
exerciser: AqProtocolExerciser,
address: int = 0,
config: PxI2C8BitAddressMemoryTargetConfig | None = None,
*args,
**kwargs
)
Bases: PxAbstractTarget[PxI2C8BitAddressMemoryTargetConfig, None]
I2C byte-addressable memory target.
Emulates a 256-byte memory device on an I2C or I3C bus. Controllers access memory using a 7-bit device address plus an 8-bit sub-address (memory offset).
Use read_mem and write_mem to access backing store from Python. Bus
reads and writes from a controller emit memory_target_read_event and
memory_target_write_event notifications.
| METHOD | DESCRIPTION |
|---|---|
add_event_handler |
Add an event handler to the current device instance, by event class or event name. |
remove_event_handler |
Remove an event handler from the current device instance, by event class or event name. |
get_event_handlers |
Retreive handlers registerd on this device. |
on_event |
Add an event handler to the instance by decorator, by event class or event name. |
match |
Return whether a device config describes a device of this class. |
update_additional_data |
Atomically update additional_data with revision-aware retry. |
update_config |
Set the config of the target. |
set_config |
Set the config of the target. |
attach_to_bus |
Attach the target to a bus. |
detach_from_bus |
Detach the device from the bus. |
perform_operation |
Send an operation. |
read_mem |
Read bytes from backing store via the Protocol Exerciser API. |
write_mem |
Write bytes to backing store via the Protocol Exerciser API. |
| ATTRIBUTE | DESCRIPTION |
|---|---|
available_events_map |
Map each available event name to its id in event topics. |
is_attached |
Check if the device is attached to a bus.
TYPE:
|
state |
Get the state of the device.
TYPE:
|
name |
Get the name of the device.
TYPE:
|
cts_op_name |
Get the name of CTS operation. Currently not available now.
TYPE:
|
additional_data |
Get the opaque additional data blob associated with this device.
TYPE:
|
config |
Get the config of the device.
TYPE:
|
address |
Static address of the device.
TYPE:
|
available_events_map
¶
Map each available event name to its id in event topics.
additional_data
¶
additional_data: bytes
Get the opaque additional data blob associated with this device.
add_event_handler
¶
Add an event handler to the current device instance, by event class or event name.
remove_event_handler
¶
remove_event_handler(
event: str | type[PxAbstractEvent], handler: Callable[[Any], Any] | None = None
) -> None
Remove an event handler from the current device instance, by event class or event name.
get_event_handlers
¶
get_event_handlers(
filter_by: Callable[[str], bool] | None = None,
) -> dict[str, list[Callable[[Any], Any]]]
Retreive handlers registerd on this device.
Handlers are always scoped to this device; an optional filter_by is
applied on friendly event names.
on_event
¶
on_event(
event_type: str | type[PxAbstractEvent],
) -> Callable[[Callable[..., Any]], Callable[..., Any]]
Add an event handler to the instance by decorator, by event class or event name.
match
¶
match(config: PxAbstractDeviceConfig) -> bool
Return whether a device config describes a device of this class.
update_additional_data
¶
Atomically update additional_data with revision-aware retry.
attach_to_bus
¶
Attach the target to a bus.
This method is used to make the device aware of the bus it is connected to. It is used to set the bus attribute of the device.
Note
This method will not automatically create an actual instance on
the Protocol Exerciser until user call the attach_to_bus method.
| PARAMETER | DESCRIPTION |
|---|---|
|
The bus to attach the device to
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the device is already attached to a bus |
detach_from_bus
¶
Detach the device from the bus.
The opposite of the attach_to_bus method.
perform_operation
¶
perform_operation(
operation: PxDeviceOperation, *, timeout: int | None = None
) -> PxDeviceOperation
read_mem
¶
Read bytes from backing store via the Protocol Exerciser API.
This does not perform an I2C bus transaction. Use a
PxI2CController to exercise the
target over the bus.
| PARAMETER | DESCRIPTION |
|---|---|
|
Starting 8-bit memory address (
TYPE:
|
|
Number of bytes to read.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[int]
|
Bytes read from backing store as a list of integers ( |
write_mem
¶
Write bytes to backing store via the Protocol Exerciser API.
This does not perform an I2C bus transaction. Use a
PxI2CController to exercise the
target over the bus.
| PARAMETER | DESCRIPTION |
|---|---|
|
Starting 8-bit memory address (
TYPE:
|
|
Bytes to write as a list of integers ( |