add, use coproc_manager
This commit is contained in:
parent
5e5d1800b6
commit
dc16588575
5 changed files with 74 additions and 40 deletions
17
py/coproc_manager.py
Normal file
17
py/coproc_manager.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import minielf
|
||||
|
||||
class Program:
|
||||
def __init__(self, filename):
|
||||
self.elf = minielf.ELFFile(open(filename, "rb"))
|
||||
code_header = self.elf.get_header_by_type(minielf.PT_LOAD)
|
||||
self.code = bytes(self.elf.pread(code_header.p_offset, code_header.p_filesz))
|
||||
self.symtab = self.elf.get_section_by_name('.symtab')
|
||||
|
||||
def get_code(self):
|
||||
return
|
||||
|
||||
def get_symbol(self, name):
|
||||
r = self.symtab.get_first_symbol_by_name(name)
|
||||
if r is None:
|
||||
raise ValueError(f"{repr(name)} not found")
|
||||
return r
|
||||
|
|
@ -1,26 +1,28 @@
|
|||
import time
|
||||
import struct
|
||||
from coproc import *
|
||||
from minidump import e, h, en
|
||||
from coproc_manager import Program
|
||||
|
||||
def storele32(cm, off, x):
|
||||
print(off, ":=", x)
|
||||
cm[off:off+4] = struct.pack("<l", x)
|
||||
def storele16(cm, off, x):
|
||||
print(off, ":=", x)
|
||||
cm[off:off+2] = struct.pack("<h", x)
|
||||
binary = e._readat(h.p_offset, h.p_filesz)
|
||||
|
||||
program = Program("/a.out-stripped")
|
||||
shared_mem = program.get_symbol('shared_mem').entry.st_value
|
||||
print(f"{shared_mem=}")
|
||||
cm = CoprocMemory(0x50000000, 8176)
|
||||
off = en.st_value
|
||||
print(f"value at {off}, adjusted offset is {off}")
|
||||
c = Coproc(binary)
|
||||
c = Coproc(program.code)
|
||||
print(f"{shared_mem=}")
|
||||
|
||||
|
||||
try:
|
||||
run(c)
|
||||
|
||||
while True:
|
||||
cm[off] = 10
|
||||
cm[shared_mem] = 10
|
||||
time.sleep(2)
|
||||
cm[off] = 20
|
||||
cm[shared_mem] = 20
|
||||
time.sleep(2)
|
||||
finally:
|
||||
print("about to halt")
|
||||
time.sleep(.2)
|
||||
halt(c)
|
||||
print("returned from halt")
|
||||
time.sleep(.2)
|
||||
|
|
|
|||
|
|
@ -6,12 +6,13 @@ a_out = open("a.out-stripped", "rb")
|
|||
e = ELFFile(a_out)
|
||||
s = e.get_section(1)
|
||||
s = e.get_section_by_name('.symtab')
|
||||
sy = s.get_symbol_by_name('shared_mem')[0]
|
||||
print(s)
|
||||
sy = s.get_first_symbol_by_name('shared_mem')
|
||||
en = sy.entry
|
||||
for h in e.iter_headers():
|
||||
if h.p_type == PT_LOAD:
|
||||
print(f"@{h.p_vaddr:04x}: Load {h.p_filesz} bytes starting at {h.p_offset}")
|
||||
content = e._readat(h.p_offset, 16)
|
||||
content = e.pread(h.p_offset, 16)
|
||||
print(" ".join(f"{b:02x}" for b in content))
|
||||
|
||||
print(f"shared_mem @ 0x{en.st_value:04x} 0x{en.st_size:04x} bytes")
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ class Section:
|
|||
self._header = sh
|
||||
|
||||
def readat(self, offset, sz):
|
||||
return self._elffile._readat(offset + self._header.sh_offset, sz)
|
||||
return self._elffile.pread(offset + self._header.sh_offset, sz)
|
||||
def constructat(self, offset, cls):
|
||||
return self._elffile._constructat(offset + self._header.sh_offset, cls)
|
||||
return self._elffile.construct_at(offset + self._header.sh_offset, cls)
|
||||
|
||||
class StringTable(Section):
|
||||
def symbolat(self, offset):
|
||||
|
|
@ -42,6 +42,15 @@ class StringTable(Section):
|
|||
result += c
|
||||
return result
|
||||
|
||||
def symbolat_matches(self, offset, name):
|
||||
stream = self._elffile.stream
|
||||
stream.seek(self._header.sh_offset + offset)
|
||||
name1 = stream.read(len(name))
|
||||
if name1 != name: return False
|
||||
nul = stream.read(1)
|
||||
if nul != b'\0': return False
|
||||
return True
|
||||
|
||||
_SymbolTableEntry = namedtuple('_SymbolTableEntry',
|
||||
['st_name', 'st_value', 'st_size', 'set_info', 'st_other', 'st_shndx'])
|
||||
|
||||
|
|
@ -54,17 +63,22 @@ class Symbol:
|
|||
self.entry = entry
|
||||
|
||||
class SymbolTable(Section):
|
||||
def __init__(self, ef, sh):
|
||||
super().__init__(ef, sh)
|
||||
self.strtab = None
|
||||
|
||||
def iter_symbols(self):
|
||||
for i in range(0, self._header.sh_size, SymbolTableEntry.calcsize()):
|
||||
yield self.constructat(i, SymbolTableEntry)
|
||||
|
||||
def get_symbol_by_name(self, name):
|
||||
def get_first_symbol_by_name(self, name):
|
||||
if not isinstance(name, bytes): name = name.encode()
|
||||
strs = self._elffile.get_section_by_name('.strtab')
|
||||
if self.strtab is None:
|
||||
self.strtab = self._elffile.get_section_by_name('.strtab')
|
||||
strtab = self.strtab
|
||||
for sy in self.iter_symbols():
|
||||
name2 = strs.symbolat(sy.st_name)
|
||||
if name == name2:
|
||||
return [Symbol(name, sy)]
|
||||
if strtab.symbolat_matches(sy.st_name, name):
|
||||
return Symbol(name, sy)
|
||||
|
||||
|
||||
section_constructors = {
|
||||
|
|
@ -84,13 +98,13 @@ class ELFFile:
|
|||
def __init__(self, stream):
|
||||
self.stream = stream
|
||||
self._buffer = ()
|
||||
if self._readat(0, 4) != b'\177ELF':
|
||||
if self.pread(0, 4) != b'\177ELF':
|
||||
raise ValueError("Not an ELF file")
|
||||
if self._readat(4, 3) != b'\1\1\1':
|
||||
if self.pread(4, 3) != b'\1\1\1':
|
||||
raise ValueError("Incompatible ELF file")
|
||||
self._header = self._constructat(0, ElfHeader32)
|
||||
self._header = self.construct_at(0, ElfHeader32)
|
||||
|
||||
def _readat(self, offset, sz):
|
||||
def pread(self, offset, sz):
|
||||
if len(self._buffer) < sz:
|
||||
self._buffer = bytearray(sz)
|
||||
self._view = memoryview(self._buffer)
|
||||
|
|
@ -99,21 +113,16 @@ class ELFFile:
|
|||
self.stream.readinto(mv)
|
||||
return mv
|
||||
|
||||
def _decodeat(self, offset, fmt):
|
||||
sz = struct.calcsize(fmt)
|
||||
mb = self._readat(offset, sz)
|
||||
return struct.unpack(fmt, mv)
|
||||
|
||||
def _constructat(self, offset, cls):
|
||||
def construct_at(self, offset, cls):
|
||||
sz = cls.calcsize()
|
||||
mb = self._readat(offset, sz)
|
||||
mb = self.pread(offset, sz)
|
||||
return cls.frombuffer(mb)
|
||||
|
||||
def get_section(self, index):
|
||||
if not (0 <= index < self._header.e_shnum):
|
||||
raise IndexError("Invalid section number")
|
||||
offset = self._header.e_shoff + index * self._header.e_shentsize
|
||||
sh = self._constructat(offset, SectionHeader32)
|
||||
sh = self.construct_at(offset, SectionHeader32)
|
||||
constructor = section_constructors.get(sh.sh_type, Section)
|
||||
return constructor(self, sh)
|
||||
|
||||
|
|
@ -126,16 +135,20 @@ class ELFFile:
|
|||
idx = self.get_section(self._header.e_shstrndx)
|
||||
for sec in self.iter_sections():
|
||||
off = sec._header.sh_name
|
||||
name2 = idx.symbolat(off)
|
||||
if name == name2:
|
||||
if idx.symbolat_matches(sec._header.sh_name, name):
|
||||
return sec
|
||||
|
||||
def get_header(self, index):
|
||||
if not (0 <= index < self._header.e_phnum):
|
||||
raise IndexError("Invalid header number")
|
||||
offset = self._header.e_phoff + index * self._header.e_phentsize
|
||||
return self._constructat(offset, HeaderTableEntry)
|
||||
return self.construct_at(offset, HeaderTableEntry)
|
||||
|
||||
def iter_headers(self):
|
||||
for i in range(self._header.e_phnum):
|
||||
yield self.get_header(i)
|
||||
|
||||
def get_header_by_type(self, p_type):
|
||||
for h in self.iter_headers():
|
||||
if h.p_type == p_type:
|
||||
return h
|
||||
|
|
|
|||
7
ulp.c
7
ulp.c
|
|
@ -15,17 +15,18 @@ EXPORT uint16_t shared_mem_len = 1024;
|
|||
#undef ULP_RISCV_CYCLES_PER_MS
|
||||
#define ULP_RISCV_CYCLES_PER_MS (int)(1000*ULP_RISCV_CYCLES_PER_US)
|
||||
|
||||
#define GPIO (GPIO_NUM_3)
|
||||
int main (void) {
|
||||
shared_mem[0] = 10;
|
||||
shared_mem_len = 1024;
|
||||
|
||||
bool gpio_level = true;
|
||||
|
||||
ulp_riscv_gpio_init(GPIO_NUM_21);
|
||||
ulp_riscv_gpio_output_enable(GPIO_NUM_21);
|
||||
ulp_riscv_gpio_init(GPIO);
|
||||
ulp_riscv_gpio_output_enable(GPIO);
|
||||
|
||||
while(1) {
|
||||
ulp_riscv_gpio_output_level(GPIO_NUM_21, gpio_level);
|
||||
ulp_riscv_gpio_output_level(GPIO, gpio_level);
|
||||
ulp_riscv_delay_cycles(shared_mem[0] * 10 * ULP_RISCV_CYCLES_PER_MS);
|
||||
gpio_level = !gpio_level;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue