Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues when using TinyUSB and FreeRTOS together #816

Merged
merged 9 commits into from
Jan 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions examples/nucleo_f429zi/usb_freertos/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2022, Raphael Lehmann
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <tusb.h>

#include <modm/board.hpp>
#include <modm/processing/rtos.hpp>
#include <modm/processing/timer/periodic_timer.hpp>

using namespace Board;

class SomeTask : modm::rtos::Thread
{
public:
SomeTask() : Thread(2, 2048, "some_task") {}

void
run()
{
modm::PeriodicTimer tmr{2.5s};
uint8_t counter{0};

while (1)
{
if (tmr.execute())
{
MODM_LOG_INFO << "SomeTask: Hello via Uart, counter=" << (counter++) << modm::endl;
}

vTaskDelay(1);
}

vTaskDelete(0);
}
};

class UsbTask : modm::rtos::Thread
{
public:
UsbTask() : Thread(1, 2048, "usb_task"), usb_io_device0{}, usb_stream0{usb_io_device0} {}

void
run()
{
MODM_LOG_INFO << "USBTask: Calling Board::initializeUsbFs() ..." << modm::endl;
Board::initializeUsbFs(4);
MODM_LOG_INFO << "USBTask: Calling tusb_init() ..." << modm::endl;
tusb_init();
MODM_LOG_INFO << "... done!" << modm::endl;

modm::PeriodicTimer tmr{2.5s};
uint8_t counter{0};

while (1)
{
tud_task();
if (tmr.execute())
{
MODM_LOG_INFO << "UsbTask: Hello via Uart, counter=" << counter << modm::endl;
usb_stream0 << "UsbTask: Hello via USB CDC, counter=" << counter << modm::endl;
counter++;
}

vTaskDelay(1);
}

vTaskDelete(0);
}

private:
modm::IODeviceWrapper<UsbUart0, modm::IOBuffer::DiscardIfFull> usb_io_device0;
modm::IOStream usb_stream0;
};

SomeTask someTask;
UsbTask usbTask;

int
main()
{
Board::initialize();
Leds::setOutput();
MODM_LOG_INFO << "Nucleo-F429ZI: TinyUSB & FreeRTOS example" << modm::endl;

MODM_LOG_INFO << "WARNING!" << modm::endl;
MODM_LOG_INFO << "TinyUSB in modm does not currently use the FreeRTOS abstraction layer";
MODM_LOG_INFO << " and is not thread-safe with FreeRTOS threads." << modm::endl;

modm::rtos::Scheduler::schedule();

// we should never get here
return 0;
}
17 changes: 17 additions & 0 deletions examples/nucleo_f429zi/usb_freertos/project.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<library>
<extends>modm:nucleo-f429zi</extends>
<options>
<option name="modm:build:build.path">../../../build/nucleo_f429zi/usb_freertos</option>
<option name="modm:tinyusb:config">device.cdc</option>
</options>
<modules>
<module>modm:build:scons</module>
<module>modm:freertos</module>
<module>modm:processing:rtos</module>
<module>modm:processing:timer</module>
<module>modm:tinyusb</module>
</modules>
<collectors>
<collect name="modm:build:cppdefines">CFG_TUSB_DEBUG=2</collect>
</collectors>
</library>
2 changes: 1 addition & 1 deletion ext/aws/FreeRTOSConfig.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ your application. */
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( {{ frequency }} )
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION {{ 0 if with_heap else 1 }}
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION {{ 1 if with_heap else 0 }}
// used by modm:platform:clock for modm::Clock::increment(): vApplicationTickHook()
#define configUSE_TICK_HOOK 1
Expand Down
2 changes: 1 addition & 1 deletion ext/aws/freertos.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ these settings:
- `configCPU_CLOCK_HZ` implemented with CMSIS `SystemCoreClock`.
- `configTICK_RATE_HZ` set to `modm:freertos:frequency` or 1kHz on Cortex-M0.
- `configSUPPORT_DYNAMIC_ALLOCATION = 1` only if used with `modm:platform:heap`.
- `configSUPPORT_STATIC_ALLOCATION = 1` only if used without `modm:platform:heap`.
- `configSUPPORT_STATIC_ALLOCATION = 1` always.
- `configUSE_TICK_HOOK = 1` used by `modm:platform:clock` to provide `modm::Clock`.

In addition we define these overwritable default settings:
Expand Down
4 changes: 2 additions & 2 deletions ext/aws/modm_port.cpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ void vPortFree(void *pv)
traceFREE(pv, 0);
}
}
%% else
%% endif

#if configUSE_TIMERS == 1
static StaticTask_t timers_task_storage;
static StackType_t timers_task_stack_storage[configTIMER_TASK_STACK_DEPTH];
Expand All @@ -91,7 +92,6 @@ void vApplicationGetIdleTaskMemory(StaticTask_t** ppxIdleTaskTCBBuffer,
*ppxIdleTaskStackBuffer = idle_task_stack_storage;
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
%% endif

%% if with_debug
#include <modm/debug.hpp>
Expand Down
35 changes: 23 additions & 12 deletions ext/hathach/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ def init(module):
module.description = FileReader("module.md")

def prepare(module, options):
if not (options[":target"].has_driver("usb") or
options[":target"].has_driver("usb_otg_fs") or
options[":target"].has_driver("usb_otg_hs") or
options[":target"].has_driver("udp") or
options[":target"].has_driver("uhp")):
device = options[":target"]
if not (device.has_driver("usb") or
device.has_driver("usb_otg_fs") or
device.has_driver("usb_otg_hs") or
device.has_driver("udp") or
device.has_driver("uhp")):
return False

configs = {"device.cdc", "device.msc", "device.vendor", "device.midi", "device.dfu"}
Expand All @@ -42,12 +43,15 @@ def prepare(module, options):
dependencies=lambda vs:
[":tinyusb:{}".format(v.replace(".", ":")) for v in vs]))

if options[":target"].has_driver("usb_otg_hs"):
# Most devices only have FS=usb, some STM32 have FS/HS=usb_otg_fs/usb_otg_hs
# and some STM32 only have HS=usb_otg_hs, so we only define this option if
# there is a choice and default this to FS by default.
if device.has_driver("usb_otg_hs") and device.has_driver("usb_otg_fs"):
module.add_option(
EnumerationOption(name="speed",
description="USB Port Speed",
enumeration={"full": "fs", "high": "hs"},
default="high" if options[":target"].has_driver("usb_otg_hs") else "full",
default="full",
dependencies=lambda s: ":platform:usb:{}s".format(s[0])))

module.add_submodule(TinyUsbDeviceModule())
Expand Down Expand Up @@ -109,19 +113,26 @@ def build(env):
tusb_config["CFG_TUSB_MCU"] = "OPT_MCU_RP2040"
env.copy("tinyusb/src/portable/raspberrypi/rp2040/", "portable/raspberrypi/rp2040/")

# TinyUSB has a OS abstraction layer for FreeRTOS, but it is causes problems with modm
# if env.has_module(":freertos"):
# tusb_config["CFG_TUSB_OS"] = "OPT_OS_FREERTOS"
# env.copy("tinyusb/src/osal/osal_freertos.h", "osal/osal_freertos.h")
rleh marked this conversation as resolved.
Show resolved Hide resolved

if env.has_module(":freertos"):
tusb_config["CFG_TUSB_OS"] = "OPT_OS_FREERTOS"
env.copy("tinyusb/src/osal/osal_freertos.h", "osal/osal_freertos.h")
else:
env.copy("tinyusb/src/osal/osal_none.h", "osal/osal_none.h")
env.log.warning("TinyUSB in modm does not currently use the FreeRTOS abstraction layer"
" and is not thread-safe with FreeRTOS threads.")

env.copy("tinyusb/src/osal/osal_none.h", "osal/osal_none.h")

if env.has_module(":debug"):
tusb_config["CFG_TUSB_DEBUG_PRINTF"] = "tinyusb_debug_printf"
# env.collect(":build:cppdefines.debug", "CFG_TUSB_DEBUG=2")

has_device = env.has_module(":tinyusb:device")
has_host = env.has_module(":tinyusb:host")
speed = env.get("speed", "fs")
# On STM32 with both speeds, the option decides, otherwise we must default
# to HS for the few STM32 with *only* usb_otg_hs, all other devices are FS.
speed = env.get("speed", "hs" if env[":target"].has_driver("usb_otg_hs") else "fs")
port = 0 if speed == "fs" else 1

mode = None
Expand Down
2 changes: 1 addition & 1 deletion ext/hathach/tusb_descriptors.c.in
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ string_desc_arr[] =
%% endfor
};

static uint16_t _desc_str[32];
static uint16_t _desc_str[33];

// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long
Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/black_pill_f103/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp>();
}

Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/black_pill_f411/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();
usb::Id::configure(Gpio::InputType::PullUp);

Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/blue_pill_f103/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp>();
}

Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/disco_f072rb/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,9 @@ initializeL3g()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp>();
}

Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/disco_f303vc/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ initializeLsm3()


inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp>();
}

Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/disco_f407vg/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ initializeMp45()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/disco_f469ni/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
Expand Down
2 changes: 1 addition & 1 deletion src/modm/board/disco_f746ng/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb_fs::Device::initialize<SystemClock>();
usb_fs::Device::connect<usb_fs::Dm::Dm, usb_fs::Dp::Dp, usb_fs::Id::Id>();
Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/disco_l476vg/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ initialize()

/// You must take out the LCD screen and close SB24 and SB25 for USB to work
inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/feather_m0/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
modm::platform::Usb::initialize<Board::SystemClock>();
modm::platform::Usb::initialize<Board::SystemClock>(priority);
modm::platform::Usb::connect<GpioA24::Dm, GpioA25::Dp>();
}

Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/nucleo_f429zi/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/nucleo_f446ze/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ initialize()
}

inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();

usb::Overcurrent::setInput();
Expand Down
4 changes: 2 additions & 2 deletions src/modm/board/nucleo_h743zi/board.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,9 @@ initialize()

/// FIXME: USB does not work on this board.
inline void
initializeUsbFs()
initializeUsbFs(uint8_t priority=3)
{
usb::Device::initialize<SystemClock>();
usb::Device::initialize<SystemClock>(priority);
usb::Device::connect<usb::Dm::Dm, usb::Dp::Dp, usb::Id::Id>();
usb::Id::configure(Gpio::InputType::Floating);

Expand Down
Loading