ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ns_usb.c File Reference

Non-Secure image: full ThreadX + USBX CDC self-loop inside TrustZone NS (#96). More...

#include <stdint.h>
#include <string.h>
#include "ns_usb_internal.h"
#include "ra8_usb.h"
#include "tx_api.h"
#include "ux_api.h"
#include "ux_dcd_ra8_usb.h"
#include "ux_device_class_cdc_acm.h"
#include "ux_device_stack.h"
#include "ux_system.h"
Include dependency graph for ns_usb.c:

Go to the source code of this file.

Enumerations

enum  tz_usb_state_t : uint32_t {
  k_tz_usb_state_stack_up = 1U ,
  k_tz_usb_state_cdc_ready = 2U ,
  k_tz_usb_state_dcd_ready = 3U ,
  k_tz_usb_state_attached = 4U ,
  k_tz_usb_state_dispatched = 5U
}
 USBX bring-up progress breadcrumbs written to g_tz_usb_state. More...
enum  ns_usb_cfg_t : uint32_t {
  k_ns_usb_thread_stack = 8192U ,
  k_ns_usb_pool_bytes = 16384U ,
  k_ns_usb_thread_prio = 8U ,
  k_ns_usb_echo_out_pipe = 2U ,
  k_ns_usb_echo_in_pipe = 1U
}
 USBX worker thread + pool tunables. More...
enum  ns_usb_langid_t : uint8_t {
  k_ns_usb_langid_lo = 0x09U ,
  k_ns_usb_langid_hi = 0x04U
}
 USBX LANGID 0x0409 (English-US), little-endian byte pair. More...

Functions

void ra8_delay_ms (uint32_t ms)
 Non-Secure ra8_delay_ms – sleep ms ThreadX ticks.
uint32_t ra8_time_ms (void)
 Non-Secure ra8_time_ms – monotonic millisecond clock from ThreadX.
static VOID ns_cdc_activate (VOID *cdc_instance)
 CDC-ACM activate callback – capture the class + enable bulk auto-echo.
static VOID ns_cdc_deactivate (VOID *cdc_instance)
 CDC-ACM deactivate callback – drop the live class pointer.
static UINT ns_usbx_stack_up (void)
 Bring the USBX system + device stack up on the FS framework.
static UINT ns_cdc_class_register (void)
 Register the CDC-ACM class against the device-stack configuration.
static VOID ns_usb_worker (ULONG arg)
 NS USBX worker – bring CDC up then poll the controller forever.
void tx_application_define (void *first_unused_memory)
 ThreadX application-define callback – spawn the device + host workers.

Variables

volatile uint32_t g_tz_nsc_cgc_usb_match
 HIL gate symbol – defined in ns_main.c, advanced by the USB worker.
volatile uint32_t g_tz_usb_state
 USBX bring-up progress breadcrumb (localises a stall under J-Link).
volatile uint32_t g_tz_usb_configured
 Advances each time the CDC-ACM activate callback fires (enumeration reached SET_CONFIGURATION – the host configured the device).
volatile uint32_t g_tz_usb_dispatch_count
 Polled-dispatch iteration counter (USB worker liveness).
volatile uint32_t g_tz_usb_intsts_or
 Bitwise OR of every INTSTS0 snapshot the worker has seen.
static TX_THREAD s_ns_usb_thread
 ThreadX TCB for the NS USBX worker.
static UCHAR s_ns_usb_stack [k_ns_usb_thread_stack]
 Stack backing storage for s_ns_usb_thread.
static UCHAR s_ns_usbx_pool [k_ns_usb_pool_bytes]
 USBX memory pool (USBX manages it as a tx_byte_pool).
static CHAR s_ns_usb_thread_name [] = "ns_usb_worker"
 Worker thread name (writable NS data; ThreadX name_ptr is CHAR*).
static UX_SLAVE_CLASS_CDC_ACM * s_ns_cdc_acm = UX_NULL
 Active CDC-ACM class instance captured by the activate callback.
static UCHAR s_ns_device_framework_fs []
static UCHAR s_ns_string_framework []
 USBX string descriptor table (vendor / product / serial).
static UCHAR s_ns_language_id_framework [] = {k_ns_usb_langid_lo, k_ns_usb_langid_hi}

Detailed Description

Non-Secure image: full ThreadX + USBX CDC self-loop inside TrustZone NS (#96).

Tag
[Ring 6 / APP] {World: NS}

This is the literal title of issue #60 – "ThreadX + USBX inside the NS image" – realised on the RAM-resident two-project NS build, taken all the way to a self-validating loop. The Secure side (trustzone_init.c), before BLXNS, routes both ports' pins, enables the USBHS PLL, sets the U15 expander to host mode, and marks USBFS + USBHS Non-secure (PSARB bits 11 + 12). From genuine Non-secure state this file runs TWO time-sliced ThreadX workers:

  • ns_usb_worker – the USBFS (J11) CDC-ACM DEVICE. Brings USBX + the ux_dcd_ra8_usb bridge up (RA8_USB_POLLED_ONLY – no USB NVIC line), attaches (D+ pull-up), then spins ra8_usb_dispatch to service chapter-9
    • bulk auto-echo (OUT pipe 2 -> IN pipe 1).
  • ns_host_worker – the USBHS (J7) polled HOST. Enumerates the looped device (GET_DESCRIPTOR / SET_ADDRESS / SET_CONFIGURATION), opens the bulk pipes, then bulk round-trips a deterministic pattern and byte-checks the echo forever, advancing g_tz_usb_host_rounds_ok (the HIL gate).

Both workers share one ThreadX priority with a 1-tick time-slice: the host's ~10 ms polling windows dwarf the slice, so the polled device dispatch is serviced inside them without any USB interrupt. The controllers are reached through the IDAU bit[28]=1 Non-secure aliases (USBFS 0x5025_0000, USBHS 0x5035_0000), injected by RA8_PERIPH_NS_ALIAS.

All RTOS objects (pool, stacks, TCB) live in NS .bss (the NS-image linker routes ordinary .bss into the SRAM2 NS alias, and ns_reset_handler zeros the whole NS BSS span before tx_kernel_enter).

The looped device identifies as 1209:000a; an external host (macOS) on J11 would also enumerate it as /dev/cu.usbmodem*.

Since
0.1.0

Definition in file ns_usb.c.

Enumeration Type Documentation

◆ ns_usb_cfg_t

enum ns_usb_cfg_t : uint32_t

USBX worker thread + pool tunables.

Enumerator
k_ns_usb_thread_stack 

Worker thread stack (bytes).

k_ns_usb_pool_bytes 

USBX memory pool (bytes).

k_ns_usb_thread_prio 

Worker priority + preempt threshold.

k_ns_usb_echo_out_pipe 

CDC bulk-OUT -> pipe 2 (auto-echo).

k_ns_usb_echo_in_pipe 

CDC bulk-IN -> pipe 1 (auto-echo).

Definition at line 174 of file ns_usb.c.

◆ ns_usb_langid_t

enum ns_usb_langid_t : uint8_t

USBX LANGID 0x0409 (English-US), little-endian byte pair.

Enumerator
k_ns_usb_langid_lo 

LANGID 0x0409 low byte.

k_ns_usb_langid_hi 

LANGID 0x0409 high byte.

Definition at line 405 of file ns_usb.c.

◆ tz_usb_state_t

enum tz_usb_state_t : uint32_t

USBX bring-up progress breadcrumbs written to g_tz_usb_state.

Each value means "execution got this far". On any bring-up error the variable freezes at the failing step, so a single J-Link read localises the stall without a debugger session.

Invariant
Values ascend in bring-up order, starting from the implicit 0 (nothing attempted yet) that zero-initialised .bss provides.
See also
g_tz_usb_state
Enumerator
k_tz_usb_state_stack_up 

USBX stack initialised.

k_tz_usb_state_cdc_ready 

CDC-ACM class registered.

k_tz_usb_state_dcd_ready 

DCD bridge installed.

k_tz_usb_state_attached 

Device attached (D+ pull-up on).

k_tz_usb_state_dispatched 

Entered the polled-dispatch loop.

Definition at line 77 of file ns_usb.c.

Function Documentation

◆ ns_cdc_activate()

VOID ns_cdc_activate ( VOID * cdc_instance)
static

CDC-ACM activate callback – capture the class + enable bulk auto-echo.

Parameters
[in]cdc_instancePointer to UX_SLAVE_CLASS_CDC_ACM.
Returns
void.
Precondition
Invoked by the USBX device stack during SET_CONFIGURATION processing (here, from inside the worker's ra8_usb_dispatch call).
_ux_system_slave is non-NULL.
Postcondition
s_ns_cdc_acm points at the live class; device state pinned CONFIGURED.
ISR-side OUT->IN auto-echo is armed; g_tz_usb_configured advanced.
Note
Runs in the polled-dispatch worker context.
Since
0.1.0

Definition at line 429 of file ns_usb.c.

References g_tz_usb_configured, k_ns_usb_echo_in_pipe, k_ns_usb_echo_out_pipe, s_ns_cdc_acm, and ux_dcd_ra8_usb_auto_echo_enable().

Referenced by ns_cdc_class_register().

◆ ns_cdc_class_register()

UINT ns_cdc_class_register ( void )
static

Register the CDC-ACM class against the device-stack configuration.

Returns
UINT UX_SUCCESS on success, propagated USBX error otherwise.
Return values
UX_SUCCESSClass registered against configuration 1, interface 0.
Precondition
ns_usbx_stack_up has succeeded.
ns_cdc_activate / ns_cdc_deactivate are defined.
Postcondition
The CDC-ACM class is bound; activate posts g_tz_usb_configured.
Read/write endpoints become available after activation.
Note
Not re-entrant.
Since
0.1.0

Definition at line 502 of file ns_usb.c.

References ns_cdc_activate(), and ns_cdc_deactivate().

Referenced by ns_usb_worker().

◆ ns_cdc_deactivate()

VOID ns_cdc_deactivate ( VOID * cdc_instance)
static

CDC-ACM deactivate callback – drop the live class pointer.

Parameters
[in]cdc_instanceUnused.
Returns
void.
Precondition
Invoked by the USBX device stack on de-configuration / detach.
s_ns_cdc_acm may or may not be set.
Postcondition
s_ns_cdc_acm is UX_NULL.
No further echo until the next activate.
Note
Runs in the polled-dispatch worker context.
Since
0.1.0

Definition at line 453 of file ns_usb.c.

References s_ns_cdc_acm.

Referenced by ns_cdc_class_register().

◆ ns_usb_worker()

VOID ns_usb_worker ( ULONG arg)
static

NS USBX worker – bring CDC up then poll the controller forever.

Parameters
[in]argUnused (ThreadX entry signature).
Returns
Never returns.
Precondition
::ns_usb_application_define auto-started this thread.
CPU is in NS thread mode; USB clock + PSARB delegation + pins are live.
Postcondition
On clean bring-up the worker loops in ra8_usb_dispatch, advancing g_tz_nsc_cgc_usb_match (the HIL gate) every iteration.
On any bring-up error g_tz_usb_state freezes at the failing step and the thread returns (worker exits; gate stops -> failure visible).
Note
Single-instance worker; not designed for re-entry.
Since
0.1.0

Definition at line 536 of file ns_usb.c.

References g_tz_nsc_cgc_usb_match, g_tz_usb_dispatch_count, g_tz_usb_intsts_or, g_tz_usb_state, k_ra8_ok, k_ra8_usb_speed_fs, k_tz_usb_state_attached, k_tz_usb_state_cdc_ready, k_tz_usb_state_dcd_ready, k_tz_usb_state_dispatched, k_tz_usb_state_stack_up, ns_cdc_class_register(), ns_usbx_stack_up(), ra8_usb_device_attach(), ra8_usb_dispatch(), ra8_usb_intsts0_snapshot(), and ux_dcd_ra8_usb_initialize().

Referenced by tx_application_define().

◆ ns_usbx_stack_up()

UINT ns_usbx_stack_up ( void )
static

Bring the USBX system + device stack up on the FS framework.

Returns
UINT UX_SUCCESS on success, propagated USBX error otherwise.
Return values
UX_SUCCESSStack initialised; class registrations accepted.
Precondition
The USBX pool s_ns_usbx_pool is zeroed NS RAM.
Called from the worker thread (USBX needs ThreadX services).
Postcondition
On success the device stack accepts class registration.
On failure USBX state is undefined; caller bails.
Note
Single call; not idempotent.
Since
0.1.0

Definition at line 475 of file ns_usb.c.

References k_ns_usb_pool_bytes, s_ns_device_framework_fs, s_ns_language_id_framework, s_ns_string_framework, and s_ns_usbx_pool.

Referenced by ns_usb_worker().

◆ ra8_delay_ms()

void ra8_delay_ms ( uint32_t ms)

Non-Secure ra8_delay_ms – sleep ms ThreadX ticks.

Busy-wait for at least ms milliseconds.

ra8_usb calls ra8_delay_ms(1) once during device bring-up. The NS image must NOT link ra8_time.c: its ra8_time_init reprograms the SysTick that ThreadX owns, and its delay else-branch waits on a tick counter the ThreadX SysTick handler never advances. ThreadX's 1 ms tick makes one sleep tick == 1 ms here. Called only from thread context.

Parameters
[in]msMilliseconds to block (0 is rounded up to one tick).
Returns
void.
Precondition
Called from ThreadX thread context (the USB worker), not an ISR.
The ThreadX scheduler is running (1 ms tick live).
Postcondition
The caller blocked for at least ms ticks.
No SysTick reconfiguration occurs.
Note
Not callable from interrupt context.
Since
0.1.0

Definition at line 143 of file ns_usb.c.

References ra8_dwt_cyccnt_read(), s_cycles_per_ms, s_tick_ms, and tx_thread_sleep.

Referenced by app_bringup_panel(), c6_cam_camera_init(), c6_fwver_worker_entry(), c6_hosted_worker_entry(), c6_join_worker_entry(), c6_probe_sweep_mode(), c6_wifi_worker_entry(), cam_bringup(), cdc_enum_hunt(), cdc_enum_set_address(), cm_bringup_panel(), demo_emit_measurement(), dfu_enum_hunt(), dfu_enum_set_address(), dfu_wait_state(), ez_bringup_panel(), gptp_measure(), hid_enum_hunt(), hid_enum_hunt(), hid_enum_set_address(), hid_enum_set_address(), internal_bring_up_sensor(), internal_c6_cam_worker_entry(), internal_ceu_wait_for_frame(), internal_cs(), internal_cs_try(), internal_dac_demo_one_triangle_period(), internal_enum_assign_addr(), internal_enum_hunt(), internal_enum_hunt(), internal_kick_net(), internal_lcd_bringup_panel(), internal_lcd_bringup_panel(), internal_lpm_demo_one_wake(), internal_pdm_prepare_hardware(), internal_poeg_demo_cycle(), internal_pull_read(), internal_ra8_epaper_pulse_reset(), internal_reset_phase_1s(), internal_reset_phase_8d(), internal_run(), internal_run_one(), internal_set_address(), internal_start_count_source(), internal_transfer(), internal_usbhs_try_clksel(), internal_wait_for_autoneg(), internal_wait_ready(), internal_wait_state(), main(), mg_bringup_panel(), ns_host_enum_hunt(), ns_host_set_address(), ra8_board_camera_delay_ms(), ra8_board_camera_reset(), ra8_board_lcd_panel_power_on(), ra8_board_xspi_pins_init(), ra8_rtc_clock_init(), ra8_sleep_ms(), sfr_bringup_panel(), sh_run(), timer_demo_one_capture(), tsn_check_time_base(), wdt_rr_arm_and_wait_for_reset(), and wifi_hal_worker_entry().

◆ ra8_time_ms()

uint32_t ra8_time_ms ( void )

Non-Secure ra8_time_ms – monotonic millisecond clock from ThreadX.

Get the current 1 kHz tick count.

The polled host ladder (cdc_enum_hunt) uses ra8_time_ms for its attach timeout. ThreadX's tick is 1 ms here, so tx_time_get (ticks since boot) is already a millisecond count. Replaces ra8_time.c (dropped from the NS link – see ra8_delay_ms).

Returns
Milliseconds since the ThreadX scheduler started.
Return values
0Immediately after the kernel starts.
Precondition
The ThreadX scheduler is running.
Called from thread context.
Postcondition
No state changes (pure read of the kernel tick).
The return value is monotonic between wraps (~49 days).
Note
Thread-safe (single-word kernel read).
Since
0.1.0

Definition at line 163 of file ns_usb.c.

References s_tick_ms, and tx_time_get.

Referenced by c6_cam_camera_capture_jpeg(), cdc_enum_hunt(), dfu_enum_hunt(), ez_poll_touch(), gptp_measure(), hid_enum_hunt(), hid_enum_hunt(), internal_enum_hunt(), internal_enum_hunt(), internal_pdm_capture(), internal_pdm_stream_data(), main(), ns_host_enum_hunt(), pp_demo_now_us(), ra8_now_ms(), sdram_demo_read_check(), sdram_demo_write_pass(), selftest_verify_mram_raw(), selftest_verify_mram_raw(), selftest_verify_mram_raw(), selftest_verify_mram_raw(), selftest_verify_ospi_raw(), sh_cover_gesture(), sh_loupe_held(), sh_run(), and tsn_check_time_base().

◆ tx_application_define()

void tx_application_define ( void * first_unused_memory)

ThreadX application-define callback – spawn the device + host workers.

Parameters
[in]first_unused_memoryThreadX free-RAM base (unused; static stacks).
Returns
void.
Precondition
Called by tx_kernel_enter after kernel init (from ns_reset_handler).
CPU is in NS state.
Postcondition
Two auto-started workers exist at k_ns_usb_thread_prio with a k_ns_time_slice time-slice, so they round-robin each tick.
The scheduler runs the FS device dispatch + the HS host ladder.
Note
Single-threaded init context. This is the ONE tx_application_define for the NS image (ns_main.c no longer defines one).
Since
0.1.0

Definition at line 587 of file ns_usb.c.

References k_ns_host_stack_bytes, k_ns_time_slice, k_ns_usb_thread_prio, k_ns_usb_thread_stack, ns_host_worker(), ns_usb_worker(), s_ns_host_stack, s_ns_host_thread, s_ns_host_thread_name, s_ns_usb_stack, s_ns_usb_thread, s_ns_usb_thread_name, TX_AUTO_START, and tx_thread_create.

Variable Documentation

◆ g_tz_nsc_cgc_usb_match

volatile uint32_t g_tz_nsc_cgc_usb_match
extern

HIL gate symbol – defined in ns_main.c, advanced by the USB worker.

HIL gate symbol – defined in ns_main.c, advanced by the USB worker.

Note
Read externally by J-Link only; the HIL gate probes this symbol.
Since
0.1.0

Definition at line 102 of file ns_main.c.

Referenced by ns_usb_worker().

◆ g_tz_usb_configured

volatile uint32_t g_tz_usb_configured

Advances each time the CDC-ACM activate callback fires (enumeration reached SET_CONFIGURATION – the host configured the device).

Note
Read externally by J-Link only.
Since
0.1.0

Definition at line 102 of file ns_usb.c.

Referenced by ns_cdc_activate().

◆ g_tz_usb_dispatch_count

volatile uint32_t g_tz_usb_dispatch_count

Polled-dispatch iteration counter (USB worker liveness).

Note
Read externally by J-Link only.
Since
0.1.0

Definition at line 110 of file ns_usb.c.

Referenced by ns_usb_worker().

◆ g_tz_usb_intsts_or

volatile uint32_t g_tz_usb_intsts_or

Bitwise OR of every INTSTS0 snapshot the worker has seen.

Non-zero proves USB bus activity (a host is driving SOF / reset / SETUP), i.e. the FS PHY + clock + NS attribution are all live.

Note
Read externally by J-Link only.
Since
0.1.0

Definition at line 120 of file ns_usb.c.

Referenced by ns_usb_worker().

◆ g_tz_usb_state

volatile uint32_t g_tz_usb_state

USBX bring-up progress breadcrumb (localises a stall under J-Link).

Takes the tz_usb_state_t values; 0 means stack-up was never reached.

Note
Read externally by J-Link only.
Since
0.1.0

Definition at line 93 of file ns_usb.c.

Referenced by ns_usb_worker().

◆ s_ns_cdc_acm

UX_SLAVE_CLASS_CDC_ACM* s_ns_cdc_acm = UX_NULL
static

Active CDC-ACM class instance captured by the activate callback.

Note
Read by worker; written by the USBX class path (same worker thread).
Since
0.1.0

Definition at line 217 of file ns_usb.c.

Referenced by ns_cdc_activate(), and ns_cdc_deactivate().

◆ s_ns_device_framework_fs

UCHAR s_ns_device_framework_fs[]
static

Definition at line 229 of file ns_usb.c.

Referenced by ns_usbx_stack_up().

◆ s_ns_language_id_framework

UCHAR s_ns_language_id_framework[] = {k_ns_usb_langid_lo, k_ns_usb_langid_hi}
static

Definition at line 410 of file ns_usb.c.

Referenced by ns_usbx_stack_up().

◆ s_ns_string_framework

UCHAR s_ns_string_framework[]
static

USBX string descriptor table (vendor / product / serial).

Since
0.1.0

Definition at line 342 of file ns_usb.c.

Referenced by ns_usbx_stack_up().

◆ s_ns_usb_stack

UCHAR s_ns_usb_stack[k_ns_usb_thread_stack]
static

Stack backing storage for s_ns_usb_thread.

Since
0.1.0

Definition at line 195 of file ns_usb.c.

Referenced by tx_application_define().

◆ s_ns_usb_thread

TX_THREAD s_ns_usb_thread
static

ThreadX TCB for the NS USBX worker.

Note
Single-writer (ThreadX in the NS image).
Since
0.1.0

Definition at line 188 of file ns_usb.c.

Referenced by tx_application_define().

◆ s_ns_usb_thread_name

CHAR s_ns_usb_thread_name[] = "ns_usb_worker"
static

Worker thread name (writable NS data; ThreadX name_ptr is CHAR*).

Since
0.1.0

Definition at line 209 of file ns_usb.c.

Referenced by tx_application_define().

◆ s_ns_usbx_pool

UCHAR s_ns_usbx_pool[k_ns_usb_pool_bytes]
static

USBX memory pool (USBX manages it as a tx_byte_pool).

Since
0.1.0

Definition at line 202 of file ns_usb.c.

Referenced by ns_usbx_stack_up().