This is a experimental implementation of a class that lets a integer be shared. If an interrupt happens while the integer is modified from thread mode, an exception is thrown.
Code: Select all
from array import array
from uctypes import addressof
class ShareExc(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class sharedint:
@micropython.asm_thumb
def addex(r0,r1,r2):
ldrex(r0, [r1, 0])
add(r0, r0, r2)
strex(r0, r0, [r1, 0])
@micropython.asm_thumb
def subex(r0,r1,r2):
ldrex(r0, [r1, 0])
sub(r0, r0, r2)
## just a delay to increase probablility to get a
## interrupt during variable manipulation
mov(r3,5)
label(loop)
sub(r3,1)
cmp(r3,0)
bne(loop)
##
strex(r0, r0, [r1, 0])
@micropython.asm_thumb
def getIPSR(r0):
MRS(r0,IPSR)
def __init__(self, val):
self.value = array('i',[val])
def getval(self):
return self.value[0]
def sub(self, a):
i = self.getIPSR()
if i != 0:
#In arm exception mode
print(i)
self.value[0] -= 1
else:
result = self.subex(addressof(self.value),a)
if result != 0:
raise ShareExc('error in sub')
def add(self, a):
i = self.getIPSR()
if i != 0:
#Int mode
self.value[0] += 1
else:
result = self.addex(addressof(self.value),a)
if result != 0:
raise ShareExc('error in add')
Code: Select all
import sharedint
import pyb
import time
from sharedint import ShareExc
a = sharedint.sharedint(5)
b=10000
def togg(t):
global a
global b
a.add(1)
b -= 1
if b==0:
pyb.LED(1).toggle()
b=10000
t = pyb.Timer(4)
t.callback(togg)
t.init(freq=10000)
def run():
c = 10000
hitcount = 0
while True:
time.sleep_us(100)
try:
a.sub(1)
c -= 1
if c==0:
print('val: ', a.getval(), 'Hitcount: ', hitcount)
pyb.LED(2).toggle()
c=10000
except ShareExc:
hitcount += 1