diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst
index c13a7391bbb12985f5bcbcadafec0f4248331de1..d1f923e31f0ae117731e808fc4ff0abbd7b32c47 100644
--- a/docs/library/micropython.rst
+++ b/docs/library/micropython.rst
@@ -112,5 +112,14 @@ Functions
    the heap may be locked) and scheduling a function to call later will lift
    those restrictions.
 
-   There is a finite stack to hold the scheduled functions and `schedule`
+   Note: If `schedule()` is called from a preempting IRQ, when memory
+   allocation is not allowed and the callback to be passed to `schedule()` is
+   a bound method, passing this directly will fail. This is because creating a
+   reference to a bound method causes memory allocation. A solution is to
+   create a reference to the method in the class constructor and to pass that
+   reference to `schedule()`. This is discussed in detail here
+   :ref:`reference documentation <isr_rules>` under "Creation of Python
+   objects".
+
+   There is a finite stack to hold the scheduled functions and `schedule()`
    will raise a `RuntimeError` if the stack is full.
diff --git a/docs/reference/isr_rules.rst b/docs/reference/isr_rules.rst
index 2db261c09ddf59aa5023c35dd572d59def7e354d..dfdee048c131062d11fe22c51367b877c5bcdd50 100644
--- a/docs/reference/isr_rules.rst
+++ b/docs/reference/isr_rules.rst
@@ -124,6 +124,32 @@ A means of creating an object without employing a class or globals is as follows
 The compiler instantiates the default ``buf`` argument when the function is
 loaded for the first time (usually when the module it's in is imported).
 
+An instance of object creation occurs when a reference to a bound method is
+created. This means that an ISR cannot pass a bound method to a function. One
+solution is to create a reference to the bound method in the class constructor
+and to pass that reference in the ISR. For example:
+
+.. code:: python
+
+    class Foo():
+        def __init__(self):
+            self.bar_ref = self.bar  # Allocation occurs here
+            self.x = 0.1
+            tim = pyb.Timer(4)
+            tim.init(freq=2)
+            tim.callback(self.cb)
+
+        def bar(self, _):
+            self.x *= 1.2
+            print(self.x)
+
+        def cb(self, t):
+            # Passing self.bar would cause allocation.
+            micropython.schedule(self.bar_ref, 0)
+
+Other techniques are to define and instantiate the method in the constructor
+or to pass :meth:`Foo.bar` with the argument *self*.
+
 Use of Python objects
 ~~~~~~~~~~~~~~~~~~~~~
 
@@ -179,6 +205,9 @@ interrupt occurs while the previous callback is executing, a further instance of
 for execution; this will run after the current instance has completed. A sustained high interrupt repetition
 rate therefore carries a risk of unconstrained queue growth and eventual failure with a ``RuntimeError``.
 
+If the callback to be passed to `schedule()` is a bound method, consider the
+note in "Creation of Python objects".
+
 Exceptions
 ----------