硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1266|回复: 0
收起左侧

[ThreadX全家桶] OpenOCD开源调试组件带的ThreadX调试信息展示功能

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115834
QQ
发表于 2021-12-8 14:46:05 | 显示全部楼层 |阅读模式


openocd/ThreadX.c at master · openocd-org/openocd (github.com)

  1. /***************************************************************************
  2. *   Copyright (C) 2011 by Broadcom Corporation                            *
  3. *   Evan Hunter - ehunter@broadcom.com                                    *
  4. *                                                                         *
  5. *   This program is free software; you can redistribute it and/or modify  *
  6. *   it under the terms of the GNU General Public License as published by  *
  7. *   the Free Software Foundation; either version 2 of the License, or     *
  8. *   (at your option) any later version.                                   *
  9. *                                                                         *
  10. *   This program is distributed in the hope that it will be useful,       *
  11. *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
  12. *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
  13. *   GNU General Public License for more details.                          *
  14. *                                                                         *
  15. *   You should have received a copy of the GNU General Public License     *
  16. *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  17. ***************************************************************************/

  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif

  21. #include <helper/time_support.h>
  22. #include <jtag/jtag.h>
  23. #include "target/target.h"
  24. #include "target/target_type.h"
  25. #include "rtos.h"
  26. #include "helper/log.h"
  27. #include "helper/types.h"
  28. #include "rtos_standard_stackings.h"

  29. static const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr);
  30. static const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr);

  31. static int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id);
  32. static int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id);

  33. static bool threadx_detect_rtos(struct target *target);
  34. static int threadx_create(struct target *target);
  35. static int threadx_update_threads(struct rtos *rtos);
  36. static int threadx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id, struct rtos_reg **reg_list, int *num_regs);
  37. static int threadx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[]);



  38. struct threadx_thread_state {
  39.         int value;
  40.         const char *desc;
  41. };

  42. static const struct threadx_thread_state threadx_thread_states[] = {
  43.         { 0,  "Ready" },
  44.         { 1,  "Completed" },
  45.         { 2,  "Terminated" },
  46.         { 3,  "Suspended" },
  47.         { 4,  "Sleeping" },
  48.         { 5,  "Waiting - Queue" },
  49.         { 6,  "Waiting - Semaphore" },
  50.         { 7,  "Waiting - Event flag" },
  51.         { 8,  "Waiting - Memory" },
  52.         { 9,  "Waiting - Memory" },
  53.         { 10, "Waiting - I/O" },
  54.         { 11, "Waiting - Filesystem" },
  55.         { 12, "Waiting - Network" },
  56.         { 13, "Waiting - Mutex" },
  57. };

  58. #define THREADX_NUM_STATES ARRAY_SIZE(threadx_thread_states)

  59. #define ARM926EJS_REGISTERS_SIZE_SOLICITED (11 * 4)
  60. static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_solicited[] = {
  61.         { 0,  -1,   32 },                /* r0        */
  62.         { 1,  -1,   32 },                /* r1        */
  63.         { 2,  -1,   32 },                /* r2        */
  64.         { 3,  -1,   32 },                /* r3        */
  65.         { 4,  0x08, 32 },                /* r4        */
  66.         { 5,  0x0C, 32 },                /* r5        */
  67.         { 6,  0x10, 32 },                /* r6        */
  68.         { 7,  0x14, 32 },                /* r7        */
  69.         { 8,  0x18, 32 },                /* r8        */
  70.         { 9,  0x1C, 32 },                /* r9        */
  71.         { 10, 0x20, 32 },                /* r10       */
  72.         { 11, 0x24, 32 },                /* r11       */
  73.         { 12, -1,   32 },                /* r12       */
  74.         { 13, -2,   32 },                /* sp (r13)  */
  75.         { 14, 0x28, 32 },                /* lr (r14)  */
  76.         { 15, -1,   32 },                /* pc (r15)  */
  77.         /*{ 16, -1,   32 },*/                /* lr (r14)  */
  78.         /*{ 17, 0x28, 32 },*/                /* pc (r15)  */
  79.         { 16, 0x04, 32 },                /* xPSR      */
  80. };
  81. #define ARM926EJS_REGISTERS_SIZE_INTERRUPT (17 * 4)
  82. static const struct stack_register_offset rtos_threadx_arm926ejs_stack_offsets_interrupt[] = {
  83.         { 0,  0x08, 32 },                /* r0        */
  84.         { 1,  0x0C, 32 },                /* r1        */
  85.         { 2,  0x10, 32 },                /* r2        */
  86.         { 3,  0x14, 32 },                /* r3        */
  87.         { 4,  0x18, 32 },                /* r4        */
  88.         { 5,  0x1C, 32 },                /* r5        */
  89.         { 6,  0x20, 32 },                /* r6        */
  90.         { 7,  0x24, 32 },                /* r7        */
  91.         { 8,  0x28, 32 },                /* r8        */
  92.         { 9,  0x2C, 32 },                /* r9        */
  93.         { 10, 0x30, 32 },                /* r10       */
  94.         { 11, 0x34, 32 },                /* r11       */
  95.         { 12, 0x38, 32 },                /* r12       */
  96.         { 13, -2,   32 },                /* sp (r13)  */
  97.         { 14, 0x3C, 32 },                /* lr (r14)  */
  98.         { 15, 0x40, 32 },                /* pc (r15)  */
  99.         { 16, 0x04, 32 },                /* xPSR      */
  100. };

  101. static const struct rtos_register_stacking rtos_threadx_arm926ejs_stacking[] = {
  102. {
  103.         .stack_registers_size = ARM926EJS_REGISTERS_SIZE_SOLICITED,
  104.         .stack_growth_direction = -1,
  105.         .num_output_registers = 17,
  106.         .register_offsets = rtos_threadx_arm926ejs_stack_offsets_solicited
  107. },
  108. {
  109.         .stack_registers_size = ARM926EJS_REGISTERS_SIZE_INTERRUPT,
  110.         .stack_growth_direction = -1,
  111.         .num_output_registers = 17,
  112.         .register_offsets = rtos_threadx_arm926ejs_stack_offsets_interrupt
  113. },
  114. };

  115. struct threadx_params {
  116.         const char *target_name;
  117.         unsigned char pointer_width;
  118.         unsigned char thread_stack_offset;
  119.         unsigned char thread_name_offset;
  120.         unsigned char thread_state_offset;
  121.         unsigned char thread_next_offset;
  122.         const struct rtos_register_stacking *stacking_info;
  123.         size_t stacking_info_nb;
  124.         const struct rtos_register_stacking* (*fn_get_stacking_info)(const struct rtos *rtos, int64_t stack_ptr);
  125.         int (*fn_is_thread_id_valid)(const struct rtos *rtos, int64_t thread_id);
  126. };

  127. static const struct threadx_params threadx_params_list[] = {
  128.         {
  129.         "cortex_m",                                /* target_name */
  130.         4,                                                        /* pointer_width; */
  131.         8,                                                        /* thread_stack_offset; */
  132.         40,                                                        /* thread_name_offset; */
  133.         48,                                                        /* thread_state_offset; */
  134.         136,                                                /* thread_next_offset */
  135.         &rtos_standard_cortex_m3_stacking,        /* stacking_info */
  136.         1,                                                        /* stacking_info_nb */
  137.         NULL,                                                /* fn_get_stacking_info */
  138.         NULL,                                                /* fn_is_thread_id_valid */
  139.         },
  140.         {
  141.         "cortex_r4",                                /* target_name */
  142.         4,                                                        /* pointer_width; */
  143.         8,                                                        /* thread_stack_offset; */
  144.         40,                                                        /* thread_name_offset; */
  145.         48,                                                        /* thread_state_offset; */
  146.         136,                                                /* thread_next_offset */
  147.         &rtos_standard_cortex_r4_stacking,        /* stacking_info */
  148.         1,                                                        /* stacking_info_nb */
  149.         NULL,                                                /* fn_get_stacking_info */
  150.         NULL,                                                /* fn_is_thread_id_valid */
  151.         },
  152.         {
  153.         "arm926ejs",                                /* target_name */
  154.         4,                                                        /* pointer_width; */
  155.         8,                                                        /* thread_stack_offset; */
  156.         40,                                                        /* thread_name_offset; */
  157.         48,                                                        /* thread_state_offset; */
  158.         136,                                                /* thread_next_offset */
  159.         rtos_threadx_arm926ejs_stacking,        /* stacking_info */
  160.         2,                                                                        /* stacking_info_nb */
  161.         get_stacking_info_arm926ejs,                /* fn_get_stacking_info */
  162.         is_thread_id_valid_arm926ejs,                /* fn_is_thread_id_valid */
  163.         },
  164. };

  165. enum threadx_symbol_values {
  166.         THREADX_VAL_TX_THREAD_CURRENT_PTR = 0,
  167.         THREADX_VAL_TX_THREAD_CREATED_PTR = 1,
  168.         THREADX_VAL_TX_THREAD_CREATED_COUNT = 2,
  169. };

  170. static const char * const threadx_symbol_list[] = {
  171.         "_tx_thread_current_ptr",
  172.         "_tx_thread_created_ptr",
  173.         "_tx_thread_created_count",
  174.         NULL
  175. };

  176. const struct rtos_type threadx_rtos = {
  177.         .name = "ThreadX",

  178.         .detect_rtos = threadx_detect_rtos,
  179.         .create = threadx_create,
  180.         .update_threads = threadx_update_threads,
  181.         .get_thread_reg_list = threadx_get_thread_reg_list,
  182.         .get_symbol_list_to_lookup = threadx_get_symbol_list_to_lookup,
  183. };

  184. static const struct rtos_register_stacking *get_stacking_info(const struct rtos *rtos, int64_t stack_ptr)
  185. {
  186.         const struct threadx_params *param = (const struct threadx_params *) rtos->rtos_specific_params;

  187.         if (param->fn_get_stacking_info)
  188.                 return param->fn_get_stacking_info(rtos, stack_ptr);

  189.         return param->stacking_info + 0;
  190. }

  191. static int is_thread_id_valid(const struct rtos *rtos, int64_t thread_id)
  192. {
  193.         const struct threadx_params *param;

  194.         if (!rtos->rtos_specific_params)
  195.                 return 0; /* invalid */

  196.         param = (const struct threadx_params *) rtos->rtos_specific_params;

  197.         if (param->fn_is_thread_id_valid)
  198.                 return param->fn_is_thread_id_valid(rtos, thread_id);

  199.         return (thread_id != 0);
  200. }

  201. static const struct rtos_register_stacking *get_stacking_info_arm926ejs(const struct rtos *rtos, int64_t stack_ptr)
  202. {
  203.         const struct threadx_params *param = (const struct threadx_params *) rtos->rtos_specific_params;
  204.         int        retval;
  205.         uint32_t flag;

  206.         retval = target_read_buffer(rtos->target,
  207.                         stack_ptr,
  208.                         sizeof(flag),
  209.                         (uint8_t *)&flag);
  210.         if (retval != ERROR_OK) {
  211.                 LOG_ERROR("Error reading stack data from ThreadX thread: stack_ptr=0x%" PRIx64, stack_ptr);
  212.                 return NULL;
  213.         }

  214.         if (flag == 0) {
  215.                 LOG_DEBUG("  solicited stack");
  216.                 return param->stacking_info + 0;
  217.         } else {
  218.                 LOG_DEBUG("  interrupt stack: %" PRIu32, flag);
  219.                 return param->stacking_info + 1;
  220.         }
  221. }

  222. static int is_thread_id_valid_arm926ejs(const struct rtos *rtos, int64_t thread_id)
  223. {
  224.         return (thread_id != 0 && thread_id != 1);
  225. }

  226. static int threadx_update_threads(struct rtos *rtos)
  227. {
  228.         int retval;
  229.         int tasks_found = 0;
  230.         int thread_list_size = 0;
  231.         const struct threadx_params *param;

  232.         if (!rtos)
  233.                 return -1;

  234.         if (!rtos->rtos_specific_params)
  235.                 return -3;

  236.         param = (const struct threadx_params *) rtos->rtos_specific_params;

  237.         if (!rtos->symbols) {
  238.                 LOG_ERROR("No symbols for ThreadX");
  239.                 return -4;
  240.         }

  241.         if (rtos->symbols[THREADX_VAL_TX_THREAD_CREATED_COUNT].address == 0) {
  242.                 LOG_ERROR("Don't have the number of threads in ThreadX");
  243.                 return -2;
  244.         }

  245.         /* read the number of threads */
  246.         retval = target_read_buffer(rtos->target,
  247.                         rtos->symbols[THREADX_VAL_TX_THREAD_CREATED_COUNT].address,
  248.                         4,
  249.                         (uint8_t *)&thread_list_size);

  250.         if (retval != ERROR_OK) {
  251.                 LOG_ERROR("Could not read ThreadX thread count from target");
  252.                 return retval;
  253.         }

  254.         /* wipe out previous thread details if any */
  255.         rtos_free_threadlist(rtos);

  256.         /* read the current thread id */
  257.         retval = target_read_buffer(rtos->target,
  258.                         rtos->symbols[THREADX_VAL_TX_THREAD_CURRENT_PTR].address,
  259.                         4,
  260.                         (uint8_t *)&rtos->current_thread);

  261.         if (retval != ERROR_OK) {
  262.                 LOG_ERROR("Could not read ThreadX current thread from target");
  263.                 return retval;
  264.         }

  265.         if ((thread_list_size  == 0) || (rtos->current_thread == 0)) {
  266.                 /* Either : No RTOS threads - there is always at least the current execution though */
  267.                 /* OR     : No current thread - all threads suspended - show the current execution
  268.                  * of idling */
  269.                 char tmp_str[] = "Current Execution";
  270.                 thread_list_size++;
  271.                 tasks_found++;
  272.                 rtos->thread_details = malloc(
  273.                                 sizeof(struct thread_detail) * thread_list_size);
  274.                 rtos->thread_details->threadid = 1;
  275.                 rtos->thread_details->exists = true;
  276.                 rtos->thread_details->extra_info_str = NULL;
  277.                 rtos->thread_details->thread_name_str = malloc(sizeof(tmp_str));
  278.                 strcpy(rtos->thread_details->thread_name_str, tmp_str);

  279.                 if (thread_list_size == 0) {
  280.                         rtos->thread_count = 1;
  281.                         return ERROR_OK;
  282.                 }
  283.         } else {
  284.                 /* create space for new thread details */
  285.                 rtos->thread_details = malloc(
  286.                                 sizeof(struct thread_detail) * thread_list_size);
  287.         }

  288.         /* Read the pointer to the first thread */
  289.         int64_t thread_ptr = 0;
  290.         retval = target_read_buffer(rtos->target,
  291.                         rtos->symbols[THREADX_VAL_TX_THREAD_CREATED_PTR].address,
  292.                         param->pointer_width,
  293.                         (uint8_t *)&thread_ptr);
  294.         if (retval != ERROR_OK) {
  295.                 LOG_ERROR("Could not read ThreadX thread location from target");
  296.                 return retval;
  297.         }

  298.         /* loop over all threads */
  299.         int64_t prev_thread_ptr = 0;
  300.         while ((thread_ptr != prev_thread_ptr) && (tasks_found < thread_list_size)) {

  301.                 #define THREADX_THREAD_NAME_STR_SIZE (200)
  302.                 char tmp_str[THREADX_THREAD_NAME_STR_SIZE];
  303.                 unsigned int i = 0;
  304.                 int64_t name_ptr = 0;

  305.                 /* Save the thread pointer */
  306.                 rtos->thread_details[tasks_found].threadid = thread_ptr;

  307.                 /* read the name pointer */
  308.                 retval = target_read_buffer(rtos->target,
  309.                                 thread_ptr + param->thread_name_offset,
  310.                                 param->pointer_width,
  311.                                 (uint8_t *)&name_ptr);
  312.                 if (retval != ERROR_OK) {
  313.                         LOG_ERROR("Could not read ThreadX thread name pointer from target");
  314.                         return retval;
  315.                 }

  316.                 /* Read the thread name */
  317.                 retval =
  318.                         target_read_buffer(rtos->target,
  319.                                 name_ptr,
  320.                                 THREADX_THREAD_NAME_STR_SIZE,
  321.                                 (uint8_t *)&tmp_str);
  322.                 if (retval != ERROR_OK) {
  323.                         LOG_ERROR("Error reading thread name from ThreadX target");
  324.                         return retval;
  325.                 }
  326.                 tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';

  327.                 if (tmp_str[0] == '\x00')
  328.                         strcpy(tmp_str, "No Name");

  329.                 rtos->thread_details[tasks_found].thread_name_str =
  330.                         malloc(strlen(tmp_str)+1);
  331.                 strcpy(rtos->thread_details[tasks_found].thread_name_str, tmp_str);

  332.                 /* Read the thread status */
  333.                 int64_t thread_status = 0;
  334.                 retval = target_read_buffer(rtos->target,
  335.                                 thread_ptr + param->thread_state_offset,
  336.                                 4,
  337.                                 (uint8_t *)&thread_status);
  338.                 if (retval != ERROR_OK) {
  339.                         LOG_ERROR("Error reading thread state from ThreadX target");
  340.                         return retval;
  341.                 }

  342.                 for (i = 0; (i < THREADX_NUM_STATES) &&
  343.                                 (threadx_thread_states[i].value != thread_status); i++) {
  344.                         /* empty */
  345.                 }

  346.                 const char *state_desc;
  347.                 if  (i < THREADX_NUM_STATES)
  348.                         state_desc = threadx_thread_states[i].desc;
  349.                 else
  350.                         state_desc = "Unknown state";

  351.                 rtos->thread_details[tasks_found].extra_info_str = malloc(strlen(
  352.                                         state_desc)+8);
  353.                 sprintf(rtos->thread_details[tasks_found].extra_info_str, "State: %s", state_desc);

  354.                 rtos->thread_details[tasks_found].exists = true;

  355.                 tasks_found++;
  356.                 prev_thread_ptr = thread_ptr;

  357.                 /* Get the location of the next thread structure. */
  358.                 thread_ptr = 0;
  359.                 retval = target_read_buffer(rtos->target,
  360.                                 prev_thread_ptr + param->thread_next_offset,
  361.                                 param->pointer_width,
  362.                                 (uint8_t *) &thread_ptr);
  363.                 if (retval != ERROR_OK) {
  364.                         LOG_ERROR("Error reading next thread pointer in ThreadX thread list");
  365.                         return retval;
  366.                 }
  367.         }

  368.         rtos->thread_count = tasks_found;

  369.         return 0;
  370. }

  371. static int threadx_get_thread_reg_list(struct rtos *rtos, int64_t thread_id,
  372.                 struct rtos_reg **reg_list, int *num_regs)
  373. {
  374.         int retval;
  375.         const struct threadx_params *param;

  376.         if (!rtos)
  377.                 return -1;

  378.         if (!is_thread_id_valid(rtos, thread_id))
  379.                 return -2;

  380.         if (!rtos->rtos_specific_params)
  381.                 return -3;

  382.         param = (const struct threadx_params *) rtos->rtos_specific_params;

  383.         /* Read the stack pointer */
  384.         int64_t stack_ptr = 0;
  385.         retval = target_read_buffer(rtos->target,
  386.                         thread_id + param->thread_stack_offset,
  387.                         param->pointer_width,
  388.                         (uint8_t *)&stack_ptr);
  389.         if (retval != ERROR_OK) {
  390.                 LOG_ERROR("Error reading stack frame from ThreadX thread");
  391.                 return retval;
  392.         }

  393.         LOG_INFO("thread: 0x%" PRIx64 ", stack_ptr=0x%" PRIx64, (uint64_t)thread_id, (uint64_t)stack_ptr);

  394.         if (stack_ptr == 0) {
  395.                 LOG_ERROR("null stack pointer in thread");
  396.                 return -5;
  397.         }

  398.         const struct rtos_register_stacking *stacking_info =
  399.                         get_stacking_info(rtos, stack_ptr);

  400.         if (!stacking_info) {
  401.                 LOG_ERROR("Unknown stacking info for thread id=0x%" PRIx64, (uint64_t)thread_id);
  402.                 return -6;
  403.         }

  404.         return rtos_generic_stack_read(rtos->target, stacking_info, stack_ptr, reg_list, num_regs);
  405. }

  406. static int threadx_get_symbol_list_to_lookup(struct symbol_table_elem *symbol_list[])
  407. {
  408.         unsigned int i;
  409.         *symbol_list = calloc(
  410.                         ARRAY_SIZE(threadx_symbol_list), sizeof(struct symbol_table_elem));

  411.         for (i = 0; i < ARRAY_SIZE(threadx_symbol_list); i++)
  412.                 (*symbol_list)[i].symbol_name = threadx_symbol_list[i];

  413.         return 0;
  414. }

  415. static bool threadx_detect_rtos(struct target *target)
  416. {
  417.         if ((target->rtos->symbols) &&
  418.                         (target->rtos->symbols[THREADX_VAL_TX_THREAD_CREATED_PTR].address != 0)) {
  419.                 /* looks like ThreadX */
  420.                 return true;
  421.         }
  422.         return false;
  423. }

  424. #if 0

  425. static int threadx_set_current_thread(struct rtos *rtos, threadid_t thread_id)
  426. {
  427.         return 0;
  428. }

  429. static int threadx_get_thread_detail(struct rtos *rtos,
  430.         threadid_t thread_id,
  431.         struct thread_detail *detail)
  432. {
  433.         unsigned int i = 0;
  434.         int retval;

  435. #define THREADX_THREAD_NAME_STR_SIZE (200)
  436.         char tmp_str[THREADX_THREAD_NAME_STR_SIZE];

  437.         const struct threadx_params *param;

  438.         if (!rtos)
  439.                 return -1;

  440.         if (thread_id == 0)
  441.                 return -2;

  442.         if (!rtos->rtos_specific_params)
  443.                 return -3;

  444.         param = (const struct threadx_params *) rtos->rtos_specific_params;

  445.         if (!rtos->symbols) {
  446.                 LOG_ERROR("No symbols for ThreadX");
  447.                 return -3;
  448.         }

  449.         detail->threadid = thread_id;

  450.         int64_t name_ptr = 0;
  451.         /* read the name pointer */
  452.         retval = target_read_buffer(rtos->target,
  453.                         thread_id + param->thread_name_offset,
  454.                         param->pointer_width,
  455.                         (uint8_t *)&name_ptr);
  456.         if (retval != ERROR_OK) {
  457.                 LOG_ERROR("Could not read ThreadX thread name pointer from target");
  458.                 return retval;
  459.         }

  460.         /* Read the thread name */
  461.         retval = target_read_buffer(rtos->target,
  462.                         name_ptr,
  463.                         THREADX_THREAD_NAME_STR_SIZE,
  464.                         (uint8_t *)&tmp_str);
  465.         if (retval != ERROR_OK) {
  466.                 LOG_ERROR("Error reading thread name from ThreadX target");
  467.                 return retval;
  468.         }
  469.         tmp_str[THREADX_THREAD_NAME_STR_SIZE-1] = '\x00';

  470.         if (tmp_str[0] == '\x00')
  471.                 strcpy(tmp_str, "No Name");

  472.         detail->thread_name_str = malloc(strlen(tmp_str)+1);

  473.         /* Read the thread status */
  474.         int64_t thread_status = 0;
  475.         retval =
  476.                 target_read_buffer(rtos->target,
  477.                         thread_id + param->thread_state_offset,
  478.                         4,
  479.                         (uint8_t *)&thread_status);
  480.         if (retval != ERROR_OK) {
  481.                 LOG_ERROR("Error reading thread state from ThreadX target");
  482.                 return retval;
  483.         }

  484.         for (i = 0; (i < THREADX_NUM_STATES) &&
  485.                         (threadx_thread_states[i].value != thread_status); i++) {
  486.                 /* empty */
  487.         }

  488.         char *state_desc;
  489.         if  (i < THREADX_NUM_STATES)
  490.                 state_desc = threadx_thread_states[i].desc;
  491.         else
  492.                 state_desc = "Unknown state";

  493.         detail->extra_info_str = malloc(strlen(state_desc)+1);

  494.         detail->exists = true;

  495.         return 0;
  496. }

  497. #endif

  498. static int threadx_create(struct target *target)
  499. {
  500.         for (unsigned int i = 0; i < ARRAY_SIZE(threadx_params_list); i++)
  501.                 if (strcmp(threadx_params_list[i].target_name, target->type->name) == 0) {
  502.                         target->rtos->rtos_specific_params = (void *)&threadx_params_list[i];
  503.                         target->rtos->current_thread = 0;
  504.                         target->rtos->thread_details = NULL;
  505.                         return 0;
  506.                 }

  507.         LOG_ERROR("Could not find target in ThreadX compatibility list");
  508.         return -1;
  509. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-21 17:53 , Processed in 0.324193 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表