/** * Test command to set ADC measure interval : battery period * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses * @remark usage: battery period vbatt|temp <period_second> * If <period_second> is equal to 0, corresponding measure is suspended */ void battery_period_tcmd_status(int argc, char **argv, struct tcmd_handler_ctx *ctx) { struct period_cfg_t period_cfg = {}; /* Check we have the correct parameters number */ if(argc != 4) { TCMD_RSP_ERROR(ctx, TCMD_BATT_ADC_PERIOD); return; } if (!isdigit(argv[3][0])){ TCMD_RSP_ERROR(ctx, TCMD_BATT_ADC_PERIOD); return; } if (!strcmp(argv[2], "vbatt")) period_cfg.cfg_type = 0; else if (!strcmp(argv[2], "temp")) period_cfg.cfg_type = 1; else{ TCMD_RSP_ERROR(ctx, TCMD_BATT_ADC_PERIOD); return; } period_cfg.new_period_ms = (uint16_t) (atoi(argv[3])) * 1000; battery_service_cmd_handler(ctx,BS_CMD_SET_MEASURE_INTERVAL,(void*)&period_cfg); }
/* Handles message for test command */ static void ui_svc_tcmd_handle_message(struct cfw_message *msg, void *param) { int ui_status; ui_srv_data_t *priv = CFW_MESSAGE_PRIV(msg); struct tcmd_handler_ctx *ctx = priv->context; char *message = balloc(BUFFER_LENGTH, NULL); switch (CFW_MESSAGE_ID(msg)) { case MSG_ID_UI_LED_RSP: case MSG_ID_UI_VIBR_RSP: ui_status = ((struct cfw_rsp_message *)msg)->status; if (ui_status == DRV_RC_OK) { TCMD_RSP_FINAL(ctx, NULL); } else { snprintf(message, BUFFER_LENGTH, "KO (status: %d)", ui_status); TCMD_RSP_ERROR(ctx, message); } break; default: /* default cfw handler */ snprintf(message, BUFFER_LENGTH, "Wrong ui_svc rsp (id: 0x%X)", CFW_MESSAGE_ID(msg)); TCMD_RSP_ERROR(ctx, message); break; } cproxy_disconnect(priv->ui_service_conn); cfw_msg_free(msg); bfree(priv); bfree(message); }
/* * Test command to get status of RTC(not config, running, finished): rtc status * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void rtc_status(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { char answer[RTC_FINISHED_STR_LEN + DOUBLE_UINT32_ANSWER_LENGTH]; uint32_t keys = 0; bool local_alarm_pending = false; uint32_t local_test_rtc = 0; uint32_t local_tcmd_user_alarm_rtc_val = 0; uint32_t local_tcmd_alarm_rtc_read = 0; keys = irq_lock(); local_alarm_pending = alarm_pending; local_test_rtc = test_rtc; local_tcmd_user_alarm_rtc_val = tcmd_user_alarm_rtc_val; local_tcmd_alarm_rtc_read = tcmd_alarm_rtc_read; irq_unlock(keys); if (local_alarm_pending) { TCMD_RSP_FINAL(ctx, "Rtc is running."); } else if (local_test_rtc) { snprintf(answer, RTC_FINISHED_STR_LEN + DOUBLE_UINT32_ANSWER_LENGTH, "Rtc finished %u %u", local_tcmd_user_alarm_rtc_val, local_tcmd_alarm_rtc_read); TCMD_RSP_FINAL(ctx, answer); } else { TCMD_RSP_ERROR(ctx, "Rtc not configured."); } }
/* * Test command to set RTC Alarm time, and start RTC: rtc alarm <rtc_alarm_time> * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void rtc_alarm_tcmd(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { struct rtc_config config = { 0 }; struct device *rtc_dev; uint32_t keys = 0; if (argc == RTC_ARG_NO && isdigit(argv[RTC_TIME_IDX][0])) { keys = irq_lock(); tcmd_user_alarm_rtc_val = (uint32_t)strtoul(argv[RTC_TIME_IDX], NULL, 10); test_rtc = 0; config.alarm_val = tcmd_user_alarm_rtc_val; config.alarm_enable = true; config.cb_fn = test_rtc_interrupt_fn; alarm_pending = true; irq_unlock(keys); rtc_dev = device_get_binding(RTC_DRV_NAME); assert(rtc_dev != NULL); rtc_dev->driver_data = (void *)ctx; rtc_enable(rtc_dev); rtc_set_config(rtc_dev, &config); rtc_set_alarm(rtc_dev, config.alarm_val); } else { TCMD_RSP_ERROR(ctx, "Usage: rtc alarm <alarm_time>"); } }
/** * Test command to launch vibra pattern : ui vibr x2|special <pattern parameters...>. * ui vibr x2 <intensity> <duration_on_1> <duration_off_1> <duration_on_2> <duration_off_2> <repetition> * ui vibr special <effect_1> <pause_1> <effect_2> <pause_2> <effect_3> <pause_3> * <effect_4> <pause_4> <effect_5> * * @param[in] argc Number of arguments in the Test Command (including group and name), * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The Test command response context */ void ui_vibr(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { int8_t ret; vibration_type pattern_type; union vibration_u *pattern = balloc(sizeof *pattern, NULL);; char *message = balloc(BUFFER_LENGTH, NULL); ui_srv_data_t *ui_srv_values = balloc(sizeof(ui_srv_data_t), NULL); ui_srv_values->context = ctx; if (_vibr_fill_pattern(&pattern_type, pattern, argc, argv) == -1) { snprintf(message, BUFFER_LENGTH, "Usage: ui vibr x2|special <pattern parameters...>"); goto err; } if ((ui_srv_values->ui_service_conn = ui_svc_tcmd_init()) == NULL) { snprintf(message, BUFFER_LENGTH, "service not registered"); goto err; } ret = ui_play_vibr_pattern(ui_srv_values->ui_service_conn, pattern_type, pattern, ui_srv_values); bfree(pattern); if (ret) { snprintf(message, BUFFER_LENGTH, "vibration pattern failed, status: %d", ret); goto err; } bfree(message); return; err: TCMD_RSP_ERROR(ctx, message); bfree(ui_srv_values); bfree(message); }
/** * Test command to launch led_blink_x2 pattern: * ui led_blink_x2 <led_number> <color_green> <color_blue> <color_red> <intensity> <duration_on_1> <duration_off_1> <duration_on_2> <duration_off_2> <repetition_count> * * @param[in] argc Number of arguments in the Test Command (including group and name), * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The Test command response context */ void ui_led_blink_x2(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { led_s *pattern; int8_t ret; char *message = balloc(sizeof(char) * BUFFER_LENGTH, NULL); ui_srv_data_t *ui_srv_values = balloc(sizeof(ui_srv_data_t), NULL); ui_srv_values->context = ctx; if (argc != 12) { snprintf(message, BUFFER_LENGTH, "Not the correct number of parameters"); goto err; } if (!(check_digit(argc, argv))) { snprintf(message, BUFFER_LENGTH, "Parameters shall be only digit"); goto err; } if ((ui_srv_values->ui_service_conn = ui_svc_tcmd_init()) == NULL) { snprintf(message, BUFFER_LENGTH, "service not registered"); goto err; } pattern = balloc(sizeof *pattern, NULL); #ifdef CONFIG_LED_MULTICOLOR /* Be careful not to put values higher than NCP5623C_PWM_MAX * defined in ncp5623c.h.*/ pattern->rgb[0].g = (uint8_t) (strtoul(argv[3], NULL, 16)); pattern->rgb[0].b = (uint8_t) (strtoul(argv[4], NULL, 16)); pattern->rgb[0].r = (uint8_t) (strtoul(argv[5], NULL, 16)); #endif pattern->intensity = (uint8_t) (atoi(argv[6])); pattern->duration[0].duration_on = (uint16_t) (atoi(argv[7])); pattern->duration[0].duration_off = (uint16_t) (atoi(argv[8])); pattern->duration[1].duration_on = (uint16_t) (atoi(argv[9])); pattern->duration[1].duration_off = (uint16_t) (atoi(argv[10])); pattern->repetition_count = (uint8_t) (atoi(argv[11])); ret = ui_play_led_pattern(ui_srv_values->ui_service_conn, (uint8_t) (atoi(argv[2])), LED_BLINK_X2, pattern, ui_srv_values); bfree(pattern); if (ret) { snprintf(message, BUFFER_LENGTH, "ui_play_led_pattern error %d", ret); goto err; } bfree(message); return; err: bfree(ui_srv_values); TCMD_RSP_ERROR(ctx, message); bfree(message); }
/** * Test command to get battery status : battery status * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void battery_tcmd_status(int argc, char **argv, struct tcmd_handler_ctx *ctx) { /* Check we have the correct parameters number */ if(argc != TCMD_REQ_LENGTH) { TCMD_RSP_ERROR(ctx, TCMD_STATUS_HEADER); return; } battery_service_cmd_handler(ctx,BS_CMD_BATT_STATUS,NULL); }
/** * Test command to get charger type : charger type * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void charger_tcmd_type(int argc, char **argv, struct tcmd_handler_ctx *ctx) { /* Check we have the correct parameters number */ if(argc != TCMD_REQ_LENGTH) { TCMD_RSP_ERROR(ctx, TCMD_CHARGER_TYPE); return; } battery_service_cmd_handler(ctx,BS_CMD_CHG_TYPE,NULL); }
/** * Test command to get battery charge cycle : battery cycle * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void battery_tcmd_cycle_get(int argc, char **argv, struct tcmd_handler_ctx *ctx) { /* Check we have the correct parameters number */ if(argc != TCMD_REQ_LENGTH) { TCMD_RSP_ERROR(ctx, TCMD_BATT_CYCLE_HEADER); return; } battery_service_cmd_handler(ctx,BS_CMD_BATT_GET_CHARGE_CYCLE,NULL); }
static void setbackend_usage(struct tcmd_handler_ctx *ctx) { char rsp_str[TCMD_RSP_LENGTH]; char *rsp_ptr = rsp_str; uint8_t i; rsp_ptr += snprintf(rsp_ptr, TCMD_RSP_LENGTH, "usage: log setbackend ["); for (i = 0; i < no_of_backends; i++) { if (!strcmp(current_backend_name, console_backend[i]->name)) { rsp_ptr += snprintf(rsp_ptr, TCMD_RSP_LENGTH, "%s*|",console_backend[i]->name); } else { rsp_ptr += snprintf(rsp_ptr, TCMD_RSP_LENGTH, "%s|",console_backend[i]->name); } } snprintf(rsp_ptr-1, TCMD_RSP_LENGTH, "]"); TCMD_RSP_ERROR(ctx, rsp_str); }
/** * Test command to launch led_none pattern: * ui led_none <led_number> * * @param[in] argc Number of arguments in the Test Command (including group and name), * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The Test command response context */ void ui_led_none(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { led_s *pattern; int8_t ret; char *message = balloc(sizeof(char) * BUFFER_LENGTH, NULL); ui_srv_data_t *ui_srv_values = balloc(sizeof(ui_srv_data_t), NULL); ui_srv_values->context = ctx; if (argc != 3) { snprintf(message, BUFFER_LENGTH, "Not the correct number of parameters"); goto err; } if (!(check_digit(argc, argv))) { snprintf(message, BUFFER_LENGTH, "led_number shall be only digit"); goto err; } if ((ui_srv_values->ui_service_conn = ui_svc_tcmd_init()) == NULL) { snprintf(message, BUFFER_LENGTH, "service not registered"); goto err; } pattern = balloc(sizeof *pattern, NULL); ret = ui_play_led_pattern(ui_srv_values->ui_service_conn, (uint8_t) (atoi(argv[2])), LED_NONE, pattern, ui_srv_values); bfree(pattern); if (ret) { snprintf(message, BUFFER_LENGTH, "ui_play_led_pattern error %d", ret); goto err; } bfree(message); return; err: bfree(ui_srv_values); TCMD_RSP_ERROR(ctx, message); bfree(message); }
/* * Test command to set initial RTC time: rtc set <time> * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void rtc_set(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { struct rtc_config config = { 0 }; uint32_t keys = 0; struct device *rtc_dev; if (argc == RTC_ARG_NO && isdigit(argv[RTC_TIME_IDX][0])) { rtc_dev = device_get_binding(RTC_DRV_NAME); assert(rtc_dev != NULL); keys = irq_lock(); tcmd_user_initial_rtc_val = (uint32_t)strtoul( argv[RTC_TIME_IDX], NULL, 10); config.init_val = tcmd_user_initial_rtc_val; irq_unlock(keys); rtc_set_config(rtc_dev, &config); TCMD_RSP_FINAL(ctx, NULL); } else { TCMD_RSP_ERROR(ctx, "Usage: rtc set <initial_time>"); } }
/* * Writes given value to a given address: mem write <size> <addr> <Val> * * @param[in] argc Number of arguments in the Test Command (including group and name), * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The opaque context to pass to responses */ void memory_write(int argc, char **argv, struct tcmd_handler_ctx *ctx) { uint32_t address, size; char *endptr = NULL; errno = 0; if (argc != WRITE_PARAM) { TCMD_RSP_ERROR(ctx, "CMD: mem write 1|2|4 addr val"); return; } address = strtoul(argv[ADDR_OFFSET], &endptr, 16); if (((errno == ERANGE) && (address == LONG_MAX || address == LONG_MIN)) || (errno != 0 && address == 0)) { TCMD_RSP_ERROR(ctx, "strtoul error"); return; } if ((endptr == argv[ADDR_OFFSET]) || (*endptr != '\0')) { TCMD_RSP_ERROR(ctx, "Address in hexa !"); return; } size = strtoul(argv[SIZE_OFFSET], &endptr, 10); if (((errno == ERANGE) && (size == LONG_MAX || size == LONG_MIN)) || (errno != 0 && size == 0)) { TCMD_RSP_ERROR(ctx, "strtoul error"); return; } if ((endptr == argv[SIZE_OFFSET]) || (*endptr != '\0')) { TCMD_RSP_ERROR(ctx, "Size 1|2|4 !"); return; } switch (size) { case 1: WRITE(uint8_t, address, ctx); break; case 2: WRITE(uint16_t, address, ctx); break; case 4: WRITE(uint32_t, address, ctx); break; default: TCMD_RSP_ERROR(ctx, "size: 1byte | 2bytes | 4bytes"); return; } }
void eval_jerry_script (int argc, char *argv[], struct tcmd_handler_ctx *ctx) { if (argc < 3) { TCMD_RSP_ERROR (ctx, NULL); help (); return; } else { OS_ERR_TYPE err; size_t str_total_length = 0; size_t *str_lens = (size_t *) balloc ((argc - 2) * sizeof(size_t), &err); if (str_lens == NULL || err != E_OS_OK) { printk ("%s: allocate memory failed!", __func__); TCMD_RSP_ERROR (ctx, NULL); return; } for (int i = 2; i < argc; ++i) { str_lens[i - 2] = strlen (argv[i]); str_total_length += str_lens[i - 2] + 1; } err = E_OS_OK; char *buffer = (char *) balloc (str_total_length, &err); if (buffer == NULL || err != E_OS_OK) { printk ("%s: allocate memory failed!", __func__); TCMD_RSP_ERROR (ctx, NULL); return; } char *p = buffer; for (int i = 2; i < argc; ++i) { for (int j =0; j < str_lens[i - 2]; ++j) { *p = argv[i][j]; ++p; } *p = ' '; ++p; } *p = '\0'; jerry_value_t eval_ret = jerry_eval (buffer, str_total_length - 1, false); if (jerry_value_is_error (eval_ret)) { jerry_resolve_error (eval_ret); TCMD_RSP_ERROR (ctx, NULL); } else { jerry_value_t args[] = {eval_ret}; jerry_value_t ret_val_print = jerry_call_function (print_function, jerry_create_undefined (), args, 1); jerry_release_value (ret_val_print); TCMD_RSP_FINAL (ctx, NULL); } jerry_release_value (eval_ret); bfree (buffer); bfree (str_lens); } }
/* * Test command for panic generator: debug panic <panic_id> * * @param[in] argc Number of arguments in the Test Command (including group and name) * @param[in] argv Table of null-terminated buffers containing the arguments * @param[in] ctx The context to pass back to responses */ void debug_panic(int argc, char *argv[], struct tcmd_handler_ctx *ctx) { volatile uint32_t panic_id; volatile uint32_t aligned_var[2] = { 0xFFFFFFFF, 0xFFFFFFFF }; volatile uint32_t unaligned_ptr; volatile int opcode = 0; #ifdef CONFIG_INTEL_QRK_WDT struct device *wdt_dev; struct wdt_config config; int res; #endif if (argc != ARGC) goto print_help; panic_id = strtoul(argv[PANIC_ID_IDX], NULL, 10); switch (panic_id) { case 0: panic_id = 123 / panic_id; TCMD_RSP_ERROR( ctx, "Division by 0 did not panic (sw implementation ?)."); break; case 1: unaligned_ptr = (uint32_t)&aligned_var; if (*((uint32_t *)(unaligned_ptr + 1))) TCMD_RSP_ERROR( ctx, "Unaligned access is allowed on this platform."); break; case 2: #ifdef CONFIG_INTEL_QRK_WDT config.timeout = 2097; // Timeout: 2.097s (for 32MHz) config.mode = WDT_MODE_INTERRUPT_RESET; extern struct device DEVICE_NAME_GET(wdt); wdt_dev = DEVICE_GET(wdt); res = wdt_set_config(wdt_dev, &config); if (res == DEV_OK) { TCMD_RSP_FINAL(ctx, "Watchdog"); irq_lock(); while (1) ; } else TCMD_RSP_ERROR(ctx, "Watchdog configuration failure"); #else TCMD_RSP_ERROR(ctx, "Watchdog not supported"); #endif break; case 3: TCMD_RSP_FINAL(ctx, "Invalid address"); *((volatile uint32_t *)0xFFFFFFFF) = 0xABCD; break; case 4: TCMD_RSP_FINAL(ctx, "App Error."); panic(0x123456); break; case 5: /* Need MMU to support stack overflow */ TCMD_RSP_ERROR(ctx, "No Stack Overflow"); break; case 6: ((void (*)(void))(&opcode))(); TCMD_RSP_FINAL(ctx, "Wrong OpCode."); break; default: TCMD_RSP_ERROR(ctx, "KO 1"); break; } return; print_help: TCMD_RSP_ERROR(ctx, "Usage: debug panic <panic_id>."); }