Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@alistair23
Copy link
Contributor

@alistair23 alistair23 commented May 17, 2020

Pull Request Overview

SparkFun have create the Artemis MCU module. It's a Ambiq Apoll3 MCU broken out so that it's ready to be used. On top of this they have a range of boards that you can use.

This PR is the first go at supporting the Apollo3 MCU and the RedBoard Artemis Nano.

Datasheet for the MCU: https://ambiqmicro.com/static/mcu/files/Apollo3_Blue_MCU_Data_Sheet_v0_11_0.pdf

What works:

  • Tock runs
  • UART with interrupts
  • LED (tested with panic handler)
  • libtock-rs apps

Testing Strategy

Running on the SparkFun RedBoard Artemis Nano.

TODO or Help Wanted

The main missing features right now are:

  • Add a Cortex-M4F crate in arch
  • Add the Apollo3 timer
  • Add the Apollo3 UART receive
  • Implement all of the GPIO functions

Not all of them need to be done before this can be merged.

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make formatall.

@alistair23
Copy link
Contributor Author

alistair23 commented May 18, 2020

Ok, so I figured out that with this diff the hard fault is fixed:

diff --git a/arch/cortex-m4/src/lib.rs b/arch/cortex-m4/src/lib.rs
index 00fe99d84..2827d602a 100644
--- a/arch/cortex-m4/src/lib.rs
+++ b/arch/cortex-m4/src/lib.rs
@@ -89,10 +89,6 @@ pub unsafe extern "C" fn generic_isr() {
     mov r0, #0
     msr CONTROL, r0
 
-    // This is a special address to return Thread mode with Main stack
-    movw LR, #0xFFF9
-    movt LR, #0xFFFF
-
     // Now need to disable the interrupt that fired in the NVIC to ensure it
     // does not trigger again before the scheduler has a chance to handle it. We
     // do this here in assembly for performance.

Any ideas what is going on here?

@hudson-ayers
Copy link
Contributor

hudson-ayers commented May 18, 2020

Those two lines of assembly write a particular EXC_RETURN value to the cortex-m4 link register.

Accordingly, This may be a clue (from ARMs notes on what registers are different for the m4f): http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0298a/BCGHEEFD.html :

"The EXC_RETURN code value which is used in the exception mechanism has an additional bit field to define floating-point stack status. When the value of EXC_RETURN[4] is 0, it indicates that the exception stack frame for an exception return contains floating-point registers. If this bit is 1, then it means the exception stack frame does not contain floating-point registers."

So perhaps this value should be different because you are using an m4f? In particular, perhaps the first line should be movw LR, #0xFFF1?

Disclaimer: I am not an expert on Tock's interrupt handling or on Cortex-m interrupt handling in general so maybe (probably?) this is totally wrong, but figured I'd post it on the off chance it is helpful

@alistair23
Copy link
Contributor Author

That changes the error from (with the two lines included):

Precise Data Bus Error:             true
Forced Hard Fault:                  true
Bus Fault Address:                  0x72616F6A
Fault Status Register (CFSR):       0x00008200
Hard Fault Status Register (HFSR):  0x40000000

To (with movw LR, #0xFFF1)

Invalid PC Load Usage Fault:        true
Forced Hard Fault:                  true
Fault Status Register (CFSR):       0x00040000
Hard Fault Status Register (HFSR):  0x40000000

So an improvement?

@hudson-ayers
Copy link
Contributor

Wait, 0-indexing - try 0xFFE9?

@alistair23
Copy link
Contributor Author

alistair23 commented May 18, 2020

That's it! Awesome

I have updated the PR description to remove the hard fault printout.

ppannuto
ppannuto previously approved these changes May 18, 2020
Copy link
Member

@ppannuto ppannuto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This. Is. Awesome.

I'm really excited to see an Ambiq chip in Tock.

We can probably get away without it for a little while, but we definitely should add a cortex-m4f arch to Tock. If we ever start using the floating point acceleration, we will need a different UKB implementation. Leaving the floating point hardware turned off so it can masquerade as a regular m4 is a good way to start though.

@rajivr
Copy link
Contributor

rajivr commented May 18, 2020

Wait, 0-indexing - try 0xFFE9?

In Interrupt mode, with an EXC_RETURN value of 0xFFFF_FFE9, we would return back to Thread mode with MSP when FPU is used. When FPU is not used the EXC_RETURN value would be 0xFFFF_FFF9.

One subtlety here is that when FPU is used, the exception stack frames are different. There is a reasonable chance that our user-space programs would break.

@hudson-ayers
Copy link
Contributor

In Interrupt mode, with an EXC_RETURN value of 0xFFFF_FFE9, we would return back to Thread mode with MSP when FPU is used. When FPU is not used the EXC_RETURN value would be 0xFFFF_FFF9.

One subtlety here is that when FPU is used, the exception stack frames are different. There is a reasonable chance that our user-space programs would break.

Looking through the apollo3 code in this PR I don't see anything that looks like it should be enabling the FPU, and per https://developer.arm.com/docs/dui0553/b/cortex-m4-peripherals/floating-point-unit-fpu/enabling-the-fpu it is disabled by default. So I wonder why 0xFFFF_FFE9 was needed to avoid a hard fault.

@rajivr
Copy link
Contributor

rajivr commented May 18, 2020

Looking through the apollo3 code in this PR I don't see anything that looks like it should be enabling the FPU, and per https://developer.arm.com/docs/dui0553/b/cortex-m4-peripherals/floating-point-unit-fpu/enabling-the-fpu it is disabled by default. So I wonder why 0xFFFF_FFE9 was needed to avoid a hard fault.

I have a strange suspicion that the MCU vendor might be enabling FPU in their mask ROM, before handing control over to us.

@alistair23 - I was wondering what is the value of the CONTROL register that you see when you set a breakpoint in reset_handler?

@alistair23
Copy link
Contributor Author

Which one is the control register?

r0             0x1d727f            1929855
r1             0xe000e104          -536813308
r2             0xffffffff          -1
r3             0xffffffff          -1
r4             0x1005ffd9          268828633
r5             0x7294              29332
r6             0x10008008          268468232
r7             0x10000ff8          268439544
r8             0x100               256
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x80000000          -2147483648
sp             0x10000e00          0x10000e00 <STACK_MEMORY+3584>
lr             0x2ec9              0x2ec9
pc             0x11b48             0x11b48 <reset_handler+136>
xpsr           0x21000000          553648128
fpscr          0x2000000           33554432
msp            0x10000e00          0x10000e00 <STACK_MEMORY+3584>
psp            0x0                 0x0
special        0x4000000           67108864

@alistair23
Copy link
Contributor Author

I have pushed an update that works with the LED now. I also have tidied up the GPIO driver (although some bits are unimplemented). I have also fixed the UART to run the callback so that multiple prints work.

Let me know what you think.

@alistair23 alistair23 force-pushed the alistair/apollo3 branch 2 times, most recently from 5c82a85 to 061d35b Compare May 19, 2020 06:17
@ppannuto
Copy link
Member

The CONTROL register isn't printed by default unfortunately. You can use the move special register (msr) instruction in assembly to load it into an architectural register. The existing context switch code has examples of how to do this.

Copy link
Contributor

@hudson-ayers hudson-ayers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are a few comments.

I do think it would be nice to figure out if the FPU can be disabled so that the interrupt handler for this chip can be the same as what we use for other m4f boards for now.

Also, the GPIO driver uses a decent amount of "magic numbers" (padkey value, etc.), but I don't think this needs to block on fixing those.

@alistair23
Copy link
Contributor Author

So after running

msr	CONTROL, r0

r0 is:

0x006d79e8

@ppannuto
Copy link
Member

Oops, sorry, that was a lazy pointer on my part. I believe that will write r0 into control; you need to MRS ( http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/Cihjcedb.html ):

mrs r0, CONTROL

In general, in ARM assembly, the leftmost operand is the destination

@alistair23
Copy link
Contributor Author

Ha, I should have thought about it and known that.

Anyway, CONTROL is apparently:

0x00000004

@rajivr
Copy link
Contributor

rajivr commented May 19, 2020

Ha, I should have thought about it and known that.

Anyway, CONTROL is apparently:

0x00000004

As I suspected, FPCA bit (Bit 2) is turned on. Could you disable it in reset handler by setting CP10 and CP11 in SCB.CPACR to 0.

@alistair23
Copy link
Contributor Author

alistair23 commented May 20, 2020

Ok. Thanks to @rajivr I can now disable the FPU and don't need anything special in the interrupt handling. It strangely needs a svc call, otherwise the FPU isn't disabled, not sure why.

Otherwise I have addressed all the comments. I'm going to mark this as ready for review.

@alistair23 alistair23 marked this pull request as ready for review May 20, 2020 02:05
@alistair23
Copy link
Contributor Author

I have the hello_world and LED blink examples work (although the timer doesn't) from libtock_rs

@alistair23
Copy link
Contributor Author

libtock-rs PR has been created: tock/libtock-rs#183

@alistair23 alistair23 force-pushed the alistair/apollo3 branch 2 times, most recently from 723b2c1 to f8a1439 Compare May 20, 2020 16:41
bors bot added a commit that referenced this pull request May 21, 2020
1870: move duplicated unhandled_interrupt code to cortex-m4 crate r=ppannuto a=hudson-ayers

### Pull Request Overview

While reviewing #1857, I noticed that apollo3 would be the fifth chip crate to introduce an identical `fn unhandled_interrupt()` definition. The assembly for checking the currently active interrupt is cortex-m4 specific, but not chip specific (https://developer.arm.com/docs/dui0553/a/the-cortex-m4-processor/programmers-model/core-registers), so I thought it would be good to cut down on duplicated code by moving this definition to the cortex-m4 crate.

Nothing stops chips from defining their own `unhandled_interrupt` if a different implementation is desired.

The cc26x2 chip previously used an `unhandled_interrupt()` that just looped forever, but I changed it to use this shared implementation as a panic seems strictly more useful than a hang.


### Testing Strategy

This pull request was tested by `make allboards`.


### TODO or Help Wanted

N/A

### Documentation Updated

- [x] No updates are required.

### Formatting

- [x] Ran `make format`.
- [x] Fixed errors surfaced by `make clippy`.


Co-authored-by: Hudson Ayers <[email protected]>
hudson-ayers
hudson-ayers previously approved these changes May 22, 2020
bradjc
bradjc previously approved these changes May 27, 2020
@alistair23 alistair23 dismissed stale reviews from bradjc and hudson-ayers via 3e4c384 May 27, 2020 16:06
@alistair23
Copy link
Contributor Author

I pushed an update with the doc fixes requested by @bradjc. This should be good to go :)

Copy link
Member

@ppannuto ppannuto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bors r+

🎉

@bors bors bot merged commit 992606b into tock:master May 28, 2020
@alistair23 alistair23 deleted the alistair/apollo3 branch May 28, 2020 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants