[Testers Needed] Mbed OS Port for Teensy 4.0

> target_compile_options(HelloWorld PRIVATE -O3)
I added this to CMakeLists.txt and recreated build/ but there was no change in performance from -Os. Any other suggestions??
thanks for tip on "mbed-baremetal"

another SystemCoreClock curiosity: if I count cycles around wait_us(1000000) with ARM_DWT_CYCCNT i get 527999885 cycles?
Code:
    cycles = ARM_DWT_CYCCNT;
     wait_us(1000000);
    cycles = ARM_DWT_CYCCNT - cycles;
    printf("%u cycles\n", cycles);
S0, mbed T4.0 is running at 528 MHz
On Teensy/Arduino T4.0 with delay(1000) i get 599999990 cycles as expected

---------------------------
Another test of counting cycles between GPS PPS interrupts on pin 7
Code:
// gpspps_cycles
#include "mbed.h"
 
#define ARM_DEMCR               (*(volatile uint32_t *)0xE000EDFC) // Debug Exception and Monitor Control
#define ARM_DEMCR_TRCENA                (1 << 24)        // Enable debugging & monitoring blocks
#define ARM_DWT_CTRL            (*(volatile uint32_t *)0xE0001000) // DWT control register
#define ARM_DWT_CTRL_CYCCNTENA          (1 << 0)                // Enable cycle count
#define ARM_DWT_CYCCNT          (*(volatile uint32_t *)0xE0001004) // Cycle count register
#define LAR (*(volatile uint32_t *)0xE0001FB0)   //lock for some STMF

InterruptIn gpspps(D7);  // LPC1768 p5, K64F/nucleo D7, L476 PD_0
volatile uint32_t ticks, cycles;
Timer t;
 
void pulse() {
    cycles = ARM_DWT_CYCCNT;
    ticks = 1;
}
 
int main() {
    uint32_t prev=0;
    
    printf("\nSystemCoreClock %d  %s %s\n",SystemCoreClock,__TIME__,__DATE__);
    gpspps.rise(&pulse);  // pps rising
    t.start();
    ARM_DEMCR |= ARM_DEMCR_TRCENA;   // enable debug/trace cycle counter
    LAR = 0xC5ACCE55;    // unlock
    ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;   // enable
    while(1) {           // wait around, interrupts will interrupt this!
        if (ticks) {
            uint32_t  d = cycles - prev;
            float ppm = (int32_t)(d - SystemCoreClock) / (SystemCoreClock / 1000000.);
            printf("%u cycles  %.3f ppm\n",d,ppm);
            ticks = 0;
            prev = cycles;
        }
    }
}
code reports
Code:
SystemCoreClock 528000000  14:10:06 Feb 10 2023
            527995204 cycles  -9.083 ppm
            527995204 cycles  -9.083 ppm
            527995216 cycles  -9.061 ppm
            527995180 cycles  -9.129 ppm
This seems to indicate mbed T4.0 is running at 528 MHz ? Similar test on arduino/teensy 4.0 with F_CPU 600MHz
Code:
599994059 cycles  -9.902 ppm
599994055 cycles  -9.908 ppm
599994051 cycles  -9.915 ppm
599994046 cycles  -9.923 ppm
599994041 cycles  -9.932 ppm
...
same drift with MCU running at 600 MHz
 
Last edited:
Aha! I solved the mystery with the core clock. Turns out someone changed the generated clock_config.c file, so the comments were no longer accurate. The punch line is, they didn't even do it properly -- after the chip goes into deep sleep and wakes up, it will end up at 600MHz, because there's other clock config code that was not affected by that MR!

I spent a good part of today updating my branch to have a redone clock adjustment system for MIMXRT105x/106x chips. First of all, I re-imported the latest MIMXRT1060_EVK SDK clock and power management code, then I refactored and removed (most of) the redundant clock configuration. Finally, I updated the MCUXpresso Config Tools-generated clock configuration to include an overdrive mode, and added a proper option to select between them (so everyone isn't stuck at 528MHz just cause some chips are).

In my branch, there's now a new option that can be placed in mbed_app.json:
Code:
"target.enable-overdrive-mode": 1
When set to 1 (the default), clocking will be configured on boot for overdrive mode (600MHz). This is usable on any MIMRT10xxD chips (e.g. MIMXRT1062DVL6). When set to 0, clocking will be configured for full-speed mode (528MHz). This is required for MIMRT10xxC chips (e.g. MIMXRT1062CVL6).

Additionally, I think there's a very strong possibility that this issue is the cause of the mysterious deep sleep issues on this target that I could never figure out. This is because the deep sleep code had not been updated, so it would try to reconfigure the core for 600MHz after exiting deep sleep, not realizing that it had been at 500MHz before. So nice job finding this one!
 
I believe you could detect at runtime whether the chip supports 600 MHz, if you wanted to do so...

fuse.png
 
Great news on 600 MHz. Paul's core has set_arm_clock(frequency) in clockspeed.c that allows you to configure clock speed from IDE or under program control. There are threads on this forum discussing heat sinks for overclocking.

Regarding -O3 optimization: I've been reading and learning more about cmake BUT have still not figured out how to configure -O3 ! :(
 
yes, i saw that and tried that. I've even tried hacking the git sources and changing all -Os to -O3 anywhere (e.g., .cmake and .json and ...), and trying things in other forums ... no luck. I have done optimization setting in RPI pico cmake builds. I can't believe it's that hard.

Thanks for your thoughts and prayers.
 
Update: Also added in teensy model identifier to the linker script.

Also, I did some more checking, and you guys are right. The CMake code I posted for setting the optimization level doesn't work -- it turns out that there's some compexities with how flags are exported by targets inside mbed-os. The -O3 flag does get added but it gets overridden by -Os which is exported by mbed-os. The only way to actually change the optimization level, aside from using "#pragma gcc optimize" is to change it globally for mbed-os using:

Code:
target_compile_options(mbed-core-flags INTERFACE -O3)
target_compile_options(mbed-os PUBLIC -O3)
target_compile_options(mbed-baremetal PUBLIC -O3)

I tested that (it can be added anywhere after "add_subdirectory(mbed-os)") and the options do correctly show up in the buildfile. But be warned, Mbed has not been tested at optimization levels other than -O0 and -Os...

Maybe the best solution would be to add a "Speed" profile alongside the current Develop, Debug, and Release ones. I can look into that if you guys want
 
OK, I am trying to go through the windows install procedure. Got to the download ninja part. Defender stops me in my tracks. It's not recognized. Tried turning off defender. No go... Any advice?
 
Does it say something like "Windows SmartScreen has protected your PC"? If so, there's a hidden button on that dialog that allows you to proceed. I think you have to click More Info first.
 
Does it say something like "Windows SmartScreen has protected your PC"? If so, there's a hidden button on that dialog that allows you to proceed. I think you have to click More Info first.

No, it says window defender has blocked the install. I tried disabling it and it still came up with the blocking message... I sent a PM as well. I take that back, it does say:
Code:
Microsoft Defender SmartScreen prevented an unrecognized app from starting. Running this app might put your PC at risk.
More info
 
You downloaded it from here right? If so I'm not really sure what's up, the only thing I can think of is that it's a false detection and you'll need to either add an exclusion for that file or get a different/older version of Ninja.
 
You downloaded it from here right? If so I'm not really sure what's up, the only thing I can think of is that it's a false detection and you'll need to either add an exclusion for that file or get a different/older version of Ninja.

Yup, just downloaded it from your link and got the same message when I tried to run it. Sorry, It has been quite a few years since I have used windows. Windows 7 was the last one I used.

EDIT: I'll keep trying...
 
Last edited:
600 mhz with -O3 also working ;)

Code:
coremark
2K performance run parameters for coremark.
CoreMark Size    : 666
Total ticks      : 1222
Total time (secs): 12.220000
Iterations/Sec   : 2454.991817
Iterations       : 30000
Compiler version : 6.3.1 20170620
Compiler flags   : 
Memory location  : STACK
seedcrc          : 0xe9f5
[0]crclist       : 0xe714
[0]crcmatrix     : 0x1fd7
[0]crcstate      : 0x8e3a
[0]crcfinal      : 0x5275
Correct operation validated. See readme.txt for run and reporting rules.
CoreMark 1.0 : 2454.991817 / 6.3.1 20170620  / STACK

mbed-baremetal T4.0
 
Last edited:
Review done. Finally have example(s) working under W11. Little more hair pulling than with Linux but very similar procedure wise...
 
Took a quick look at USB, but I'm stuck on lack of working printf().

If I change mbed_app.json to this (from msg #32)

Code:
{
    "target_overrides": {
        "*": {
            "platform.stdio-baud-rate": 115200,
            "platform.stdio-buffered-serial": 1,[COLOR=#008000]
            "target.console-usb": false,
            "target.console-uart": true[/COLOR]
        }
    }
}

...then printf() works (at least in main.cpp) but USB is completely removed.

Can anyone give me a mbed_app.json recipe that enables printf() to Serial1 and also builds the USB code?

Just to be more specific, I need printf() working inside usb_device_ehci.c, not just main.cpp. In other words, like this:

Code:
usb_status_t USB_DeviceEhciInit(uint8_t controllerId,
                                usb_device_handle handle,
                                usb_device_controller_handle *ehciHandle)
{
    usb_device_ehci_state_struct_t *ehciState;
    uint32_t ehci_base[] = USBHS_BASE_ADDRS;
    uint8_t intanceIndex;

    [COLOR=#008000]printf("Hello World from inside usb_device_ehci.c, controllerId = %u\n", controllerId);[/COLOR]

Just for fun, I tried this anyway with the default mbed_app.json. Result is the 4 fast / 4 slow blink of death.

Also, would be really ideal if I could somehow configure a polling-only driver for serial, so it's safer to print stuff from within interrupts. Is that an option?
 
My limited experience with RPI pico cmake, you could set both uart and usb to "true" in the json file, but that doesn't appear to work on mbed ce.

My morse code output works on pin 13, but my "decoder" measuring pulse widths on another teensy isn't that robust .

maybe use sprintf() to build a message and then use SPI or I2C to send it to another Teensy ....

hook up simple display?
 
All good ideas, but I have extremely limited time to fiddle with Mbed OS.

If Jamie (or anyone) can give me a mbed_app.json that lets printf() work inside usb_device_ehci.c, I'll poke around. I do know the USB hardware and USB protocol very well, and I can mostly follow the overly long names and coding style. Even if I don't get it working, odds are pretty good I'll uncover something that helps shine some light on why it's broken. Maybe it'll lead to a solution.

But wiring up more hardware and writing code on unfamiliar Mbed OS APIs for that hardware is way beyond the time I'm willing to commit. Likewise for learning mbed_app.json. Just don't have the time.
 
@MultipleMonomials - Setup mbed-os master branch. The 'Hello World' example fails. Blinking orange LED. This is after the merge. I am also still getting the link error seen in post #34. missing space before the '=' in line #26. If I go back to the 'de/fix-teensy4-issues everything we have done up to this point works...

EDIT: Just inspected 'MIMXRT1052xxxxx.ld' in the master branch. Line #88 is still showing:
Code:
ivt_begin= ORIGIN(m_flash_config) + LENGTH(m_flash_config);
. Very odd.
 
Last edited:
@Paul - I'm not sure if this will help or if you have already run into this but I programed the T40 after setting "target.console-usb": true in mbed_app.json. It failed to communicate but there were no death flashes from the LED. I decided to switch from Windows to Linux and when I restarted the computer with the T40 still plugged in I saw these messages when Linux was booting up:
Code:
[    7.353896] usb 1-4: device descriptor read/64, error -110
[   22.969900] usb 1-4: device descriptor read/64, error -110
[   28.857902] usb 1-4: device descriptor read/64, error -110
[   44.474169] usb 1-4: device descriptor read/64, error -110

[   55.249783] usb 1-4: device not accepting address 5, error -71
[   65.669782] usb 1-4: device not accepting address 6, error -71

This is the dmesg dump of it as I could not copy the console screen fast enough. Maybe a clue maybe not...
 
wwatson, I think you might have had an issue with checking out the latest master branch. I can see that that line is fixed in the GitHub repo here. Try this (from the mbed-ce-hello-world directory):

Code:
cd mbed-os
git checkout master
git pull origin master


EDIT: Actually no, I don't think that will work. Try following the unshallow instructions at the bottom of this page, that should do it.
 
Last edited:
wwatson, I think you might have had an issue with checking out the latest master branch. I can see that that line is fixed in the GitHub repo here. Try this (from the mbed-ce-hello-world directory):

Code:
cd mbed-os
git checkout master
git pull origin master


EDIT: Actually no, I don't think that will work. Try following the unshallow instructions at the bottom of this page, that should do it.

I remember seeing that before. I will give it a try tomorrow. Won't have time tonight. Thanks...
 
It failed to communicate but there were no death flashes from the LED. I decided to switch from Windows to Linux and when I restarted the computer with the T40 still plugged in I saw these messages when Linux was booting up:

Pretty sure that's the same USB behavior I saw in msg #28 and #29. USB enumeration begins, which means the software was at least able to correctly turn on the USB PHY and USB controller into device mode. Device hardware responds with ACK to the host's setup tokens (done automatically by hardware) but never responds to any of the host's IN tokens (requires software working).

It's really trying to work...

I need working printf() to Serial1 inside usb_device_ehci.c to dig into the problem. If I put any printf() inside that file it compiles without error, I get the 4+4 blink of death when it runs.
 
Back
Top