Skip to content

Commit efbb1c0

Browse files
committed
Thread safe pipe for connectivity periperhal IO
1 parent c63335b commit efbb1c0

File tree

2 files changed

+78
-26
lines changed

2 files changed

+78
-26
lines changed

qiling/hw/char/stm32f4xx_usart.py

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
import ctypes
77

88
from qiling.hw.peripheral import QlPeripheral
9+
from qiling.hw.connectivity import QlConnectivityPeripheral
910
from qiling.hw.const.stm32f4xx_usart import USART_SR, USART_CR1
1011

11-
class STM32F4xxUsart(QlPeripheral):
12+
class STM32F4xxUsart(QlConnectivityPeripheral):
1213
class Type(ctypes.Structure):
1314
""" the structure available in :
1415
stm32f413xx.h
@@ -56,9 +57,6 @@ def __init__(self, ql, label, intn=None):
5657

5758
self.intn = intn
5859

59-
self.recv_buf = bytearray()
60-
self.send_buf = bytearray()
61-
6260
@QlPeripheral.debug_info()
6361
def read(self, offset: int, size: int) -> int:
6462
buf = ctypes.create_string_buffer(size)
@@ -92,32 +90,13 @@ def transfer(self):
9290
data = self.usart.DR
9391

9492
self.usart.SR |= USART_SR.TXE
95-
self.send_buf.append(data)
93+
self.send_to_user(data)
9694

9795
if not (self.usart.SR & USART_SR.RXNE):
9896
# TXE bit must had been cleared
99-
if self.recv_buf:
97+
if self.can_recv():
10098
self.usart.SR |= USART_SR.RXNE
101-
self.usart.DR = self.recv_buf.pop(0)
102-
103-
104-
def send(self, data: bytes):
105-
""" send user data into USART.
106-
107-
Args:
108-
data (bytes): Input Data
109-
"""
110-
self.recv_buf += data
111-
112-
def recv(self) -> bytes:
113-
""" receive data from USART.
114-
115-
Returns:
116-
bytes: USART send buffer data
117-
"""
118-
data = bytes(self.send_buf)
119-
self.send_buf.clear()
120-
return data
99+
self.usart.DR = self.recv_from_user()
121100

122101
def step(self):
123102
self.transfer()

qiling/hw/connectivity.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Cross Platform and Multi Architecture Advanced Binary Emulation Framework
4+
#
5+
6+
7+
import ctypes
8+
import queue
9+
10+
from qiling.core import Qiling
11+
from qiling.hw.peripheral import QlPeripheral
12+
13+
14+
class QlConnectivityPeripheral(QlPeripheral):
15+
class Type(ctypes.Structure):
16+
""" Define the reigister fields of peripheral.
17+
18+
Example:
19+
fields_ = [
20+
('SR' , ctypes.c_uint32),
21+
('DR' , ctypes.c_uint32),
22+
('BRR' , ctypes.c_uint32),
23+
('CR1' , ctypes.c_uint32),
24+
('CR2' , ctypes.c_uint32),
25+
('CR3' , ctypes.c_uint32),
26+
('GTPR', ctypes.c_uint32),
27+
]
28+
"""
29+
_fields_ = []
30+
31+
def __init__(self, ql: Qiling, label: str):
32+
super().__init__(ql, label)
33+
34+
self.rtube = queue.Queue()
35+
self.wtube = queue.Queue()
36+
37+
def send(self, data: bytes):
38+
""" Send data into the peripheral.
39+
40+
Example:
41+
ql.hw.usart1.send(b'hello')
42+
"""
43+
44+
for byte in bytearray(data):
45+
self.rtube.put(byte)
46+
47+
def recv(self, numb:int = 4096) -> bytes:
48+
""" Receive data from peripheral
49+
50+
Example:
51+
data = ql.hw.i2c1.send()
52+
"""
53+
data = bytearray()
54+
while not self.wtube.empty() and numb != 0:
55+
data.append(self.wtube.get())
56+
numb -= 1
57+
58+
return bytes(data)
59+
60+
def can_recv(self):
61+
return not self.rtube.empty()
62+
63+
def recv_from_user(self) -> bytes:
64+
""" Read single byte from user input
65+
"""
66+
67+
return self.rtube.get()
68+
69+
def send_to_user(self, data: int):
70+
""" send single byte to user
71+
"""
72+
73+
self.wtube.put(data)

0 commit comments

Comments
 (0)