From a79512b841c12690b8d3e7f57d2977ae4960d6a4 Mon Sep 17 00:00:00 2001 From: John Hall Date: Mon, 23 May 2022 11:01:12 -0700 Subject: [PATCH] Updating to expect frequency units for clock and trace flags. Making sure trace frequency is not less than 1/5 of the system frequency. --- src/st-trace/trace.c | 68 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 12 deletions(-) diff --git a/src/st-trace/trace.c b/src/st-trace/trace.c index e5ee734f0..965178a70 100644 --- a/src/st-trace/trace.c +++ b/src/st-trace/trace.c @@ -98,13 +98,53 @@ static void usage(void) { puts(" -V, --version Print this version"); puts(" -vXX, --verbose=XX Specify a specific verbosity level (0..99)"); puts(" -v, --verbose Specify a generally verbose logging"); - puts(" -cXX, --clock=XX Specify the core frequency in MHz"); - puts(" -tXX, --trace=XX Specify the trace frequency in Hz"); + puts(" -cXX, --clock=XX Specify the core frequency"); + puts(" -tXX, --trace=XX Specify the trace frequency"); puts(" -n, --no-reset Do not reset board on connection"); puts(" -sXX, --serial=XX Use a specific serial number"); puts(" -f, --force Ignore most initialization errors"); } +static bool parse_frequency(char* text, uint32_t* result, double default_scale) +{ + if (text == NULL) { + ELOG("Invalid frequency.\n"); + return false; + } + + char* suffix = text; + double value = strtod(text, &suffix); + + if (value == 0.0) { + ELOG("Invalid frequency.\n"); + return false; + } + + for (int i = 0; suffix[i] != 0; i++) + suffix[i] = tolower(suffix[i]); + + double scale = default_scale; + if (strcmp(suffix, "hz") == 0) + scale = 1; + else if (strcmp(suffix, "khz") == 0) + scale = 1000; + else if (strcmp(suffix, "mhz") == 0) + scale = 1000000; + else if (strcmp(suffix, "ghz") == 0) + scale = 1000000000; + else + WLOG("Frequency is missing units of Hz, kHz, MHz, or GHz.\n"); + + value *= scale; + if (value <= 0 || value > 0xFFFFFFFFul) { + ELOG("Frequency is out of valid range.\n"); + return false; + } + + *result = (uint32_t)value; + return true; +} + bool parse_options(int argc, char **argv, st_settings_t *settings) { static struct option long_options[] = { @@ -150,10 +190,12 @@ bool parse_options(int argc, char **argv, st_settings_t *settings) { ugly_init(settings->logging_level); break; case 'c': - settings->core_frequency = atoi(optarg) * 1000000; + if (!parse_frequency(optarg, &settings->core_frequency, 1000000)) + error = true; break; case 't': - settings->trace_frequency = atoi(optarg); + if (!parse_frequency(optarg, &settings->trace_frequency, 1)) + error = true; break; case 'n': settings->reset_board = false; @@ -272,9 +314,8 @@ static bool enable_trace(stlink_t *stlink, const st_settings_t *settings, stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - ILOG("Trace Port Interface configured to expect a %d MHz system clock.\n", - system_clock_speed_mhz); + ILOG("Trace Port Interface configured to expect a %d Hz system clock.\n", + system_clock_speed); } else { WLOG("Trace Port Interface not configured. Specify the system clock with " "a --clock=XX command\n"); @@ -444,9 +485,8 @@ static void check_for_configuration_error(stlink_t *stlink, st_trace_t *trace, stlink_read_debug32(stlink, STLINK_REG_TPI_ACPR, &prescaler); if (prescaler) { uint32_t system_clock_speed = (prescaler + 1) * trace_frequency; - uint32_t system_clock_speed_mhz = (system_clock_speed + 500000) / 1000000; - WLOG("Verify the system clock is running at %d MHz.\n", - system_clock_speed_mhz); + WLOG("Verify the system clock is running at %d Hz.\n", + system_clock_speed); } WLOG("Try specifying the system clock with the --clock=XX command line " "option.\n"); @@ -563,9 +603,13 @@ int main(int argc, char **argv) { uint32_t trace_frequency = settings.trace_frequency; if (!trace_frequency) trace_frequency = STLINK_DEFAULT_TRACE_FREQUENCY; - if (trace_frequency > stlink->max_trace_freq) { + uint32_t max_trace_frequency = stlink->max_trace_freq; + if (settings.core_frequency != 0) + if (max_trace_frequency > settings.core_frequency / 5) + max_trace_frequency = settings.core_frequency / 5; + if (trace_frequency > max_trace_frequency) { ELOG("Invalid trace frequency %d (max %d)\n", trace_frequency, - stlink->max_trace_freq); + max_trace_frequency); if (!settings.force) return APP_RESULT_UNSUPPORTED_TRACE_FREQUENCY; }