This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM3352: Local variables can't be watched during CCS u-boot debug .

Part Number: AM3352

I checked this page training.ti.com/linux-board-porting-series-module-7-debugging-u-boot-jtag-ccs .
Then I understood how to debug u-boot by CCS.
I succeeded in stopping at hardware breakpoint.
But I met a problem that local variable can't be watched.

As shown in Fig.1, I tried to click "fs_type" to watch this value, but value was not displayed and "Variables" window in the upper right corner displayed nothing in spite of "fs_type" was the first argument of fs_set_blk_dev() .
Could you please teach me how to watch local variables ?

As a supplementary explanation, optimization of fs.c was removed to debug this file as shown in Fig.2 .

On the other hand, I confirmed to watch local variables when SPL debugging (not u-boot) .

Fig.1

Fig.2

  • Could you please teach me how to watch local variables ?

    You can try to use global variables just for debugging purpose.

    As a supplementary explanation, optimization of fs.c was removed to debug this file as shown in Fig.2 .

    Even with "-O0", you may still not be able to watch local variables, because some passes during compilation that collect debug information are disabled with "-O0". You can try "-Og" instead. Please refer to the gnu compiler documentation.

    Regards,

    Jianzhong

  • Thank you for reply.
    I tried "-Og" instead of "-O0".
    But this problem still occurred.
    This problem is not only local variables, but also global variables and static variables.

    I checked this video again.
    training.ti.com/linux-board-porting-series-module-7-debugging-u-boot-jtag-ccs

    In this video, the first argument "int speed" of i2c_init() function defined in omap24xx_i2c.c was displayed when hover overring around "speed" as shown in Fig.1 and Fig.2 .
    But I can't find i2c_init() function in omap24xx_i2c.c.
    So, I can't try the same way which was demonstrated in this video.

    By the way, I tried to hover over arguments of fs_set_blk_dev() function defined in fs/fs.c . Though this function has three arguments, any arguments was not displayed. Additionally, I tried a lot of functions, but the same problem occurred.

    Could you please teach me why this video succeeded in displaying local variable "speed" ? Is there something additional step to display ?

    Fig.1

    Fig.2

  • Hello,

    Please make sure the compiler option for that specific source code is changed. Please also check the GNU compiler documentation regarding  keeping debug symbols: gcc.gnu.org/.../Optimize-Options.html.

    Also to clarify, what do you need or intend to do by debugging the U-Boot? Did you run into problems with U-Boot? There may be other ways to help you than debugging the U-Boot in CCS.

    Thanks and regards,

    Jianzhong

  • Thank you for reply.
    I checked the page above, but I haven't been able to find any solution yet.

    In this thread e2e.ti.com/.../am3352-dual-bank-firmware-update-method , I got a reply that u-boot customization is needed.
    So I'm debugging u-boot, but variables aren't displayed.
    I fell into difficult situation to debug u-boot.
    I'm using u-boot source code in the latest AM3352's SDK, and didn't change any compilation option except for "-Og" in fs/fs.c .

    Any advice would be appreciated.

  • Hello,

    Sorry for our delayed response. I was out for a few days. I'll loop in our U-Boot expert to help out.

    Thank you for your patience.

    Regards,

    Jianzhong

  • Hello,
    I'm attaching two files when running "i2c dev 0" cmd @u-boot prompt for your reference:
    - am3_i2c_dev_0_bkpt.jpg: the screen-shot when hitting the the bkpt @ the entry of __omap24_i2c_setspeed().
    - am3_i2c_dev_0_call_flow.txt: the call flow when hitting the above bkpt.
    FYI: I'm using Lauterbach T32 JTAG debugger on AM335x GP EVM.
    Best,
    -Hong

    B::Register
    N N  R0   44E0B000  R8   9DF54A28  ^S+ ^Stack_+
    Z _  R1          1  R9   9DF46EB8
    C _  R2   00061A80  R10      03E8
    V _  R3   9DF54A38  R11      03E8
    Q _  R4   44E0B000  R12         0
         R5   9FFC2487  R13  9DF38620
    0 _  R6          1  R14  9FF87E0D
    1 _  R7          2  PC   9FF877B0
    2 _  SPSR        0  CPSR 800001B3
    3 _
    4 _  USR:           FIQ:
         R8   9DF54A28  R8   FCFCBA32
         R9   9DF46EB8  R9   EE37D7FD
    I I  R10      03E8  R10  DF3DBACF
    F _  R11      03E8  R11  9D8DE22F
         R12         0  R12  F7FF71FB
    T T  R13         0  R13         0
    J _  R14         0  R14         0
    svc                 SPSR        0
    nsec
         SVC:           IRQ:
    A A  R13  9DF38620  R13  E293EAEE
    E _  R14  9FF87E0D  R14  36FF8CBF
         SPSR        0  SPSR        0
    0 _
    1 _  UND:           ABT:
    2 _  R13  F5FFD5EA  R13         0
    3 _  R14  A06B494C  R14         0
         SPSR        0  SPSR        0
    
         MON:
         R13
         R14
         SPSR
    B::Var.Frame_%DECIMAL_/Locals_/Caller
    -000|__omap24_i2c_setspeed(
        |    i2c_base = 0x44E0B000,
        |    ip_rev = 1 = 0x1,
        |    speed = 400000 = 0x00061A80,
        |    waitdelay = 0x9DF54A38)
        |  fclk = 48000 = 0xBB80
        |
    -001|__omap24_i2c_init(inline)
    -001|omap_i2c_probe(
        |  ?)
        |  priv = 0x9DF54A28
        |  waitdelay = 0x9DF54A38
        |  speed = 400000 = 0x00061A80
        |  ip_rev = 1 = 0x1
        |  i2c_base = 0x44E0B000
        |  __v = 2 = 0x2
        |  reg = 9 = 0x9
        |  val = 32768 = 0x8000
        |  base = 0x44E0B000
        |  __v = 32768 = 0x8000
        |  __v = 0 = 0x0
        |  __v = 65535 = 0xFFFF
        |
        |        }
        |
        |        if (__omap24_i2c_setspeed(i2c_base, ip_rev, speed, waitdelay)) {
    -002|device_probe(inline)
    -002|device_probe(
        |    dev = 0x9DF476F0)
        |  size = 0 = 0x0
        |  dev = 0x9DF476F0
        |  drv = 0x9FFD2694
        |  ret = 1155575808 = 0x44E0B000
        |
        |                ret = drv->probe(dev);
    -003|uclass_get_device_tail(inline)
    -003|uclass_get_device_tail(
        |    dev = 0x9DF476F0,
        |  ?,
        |    devp = 0x9DF3868C)
        |  ret = 1155575808 = 0x44E0B000
        |  devp = 0x9DF3868C
        |  dev = 0x9DF476F0
        |
        |...
        |        uclass_foreach_dev(dev, uc) {
        |                if (dev->driver == find_drv)
        |                        return uclass_get_device_tail(dev, 0, devp);
        |        }
        |
        |        return -ENODEV;
        |}
        |
        |int uclass_get_device_tail(struct udevice *dev, int ret, struct udevice **devp)
        |                return ret;
        |
        |        assert(dev);
        |        ret = device_probe(dev);
    -004|uclass_get_device_by_seq(
        |  spid = UCLASS_I2C = 32 = 0x20,
        |  ipseq = 0 = 0x0,
        |  i2devp = 0x9DF3868C)
        |  return = 1155575808 = 0x44E0B000
        |  dev = 0x9DF476F0
        |
        |        }
        |        return uclass_get_device_tail(dev, ret, devp);
    -005|cmd_i2c_set_bus_num(inline)
    -005|do_i2c_bus_num(
        |  ?,
        |  ?,
        |  ?,
        |  ?)
        |debus_no = 0 = 0x0
        |debusnum = 0 = 0x0
        |  bus = 0x0
        |  ret = 1155575808 = 0x44E0B000
        |
        |...
        |#define DEFAULT_ADDR_LEN        (-1)
        |#else
        |#define DEFAULT_ADDR_LEN        1
        |#endif
        |
        |#ifdef CONFIG_DM_I2C
        |static struct udevice *i2c_cur_bus;
        |
        |static int cmd_i2c_set_bus_num(unsigned int busnum)
        |{
        |        struct udevice *bus;
        |        int ret;
        |
        |        ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
        |#ifdef CONFIG_DM_I2C
        |                ret = cmd_i2c_set_bus_num(bus_no);
    -006|cmd_call(inline)
    -006|cmd_process(
        |  ?,
        |    argc = 3 = 0x3,
        |    argv = 0x9DF54988,
        |  t repeatable = 0x9FFD3AD4,
        |    ticks = 0x0)
        |  cmdtp = 0x9FFD1F18
        |  argv = 0x9DF54988
        |  argc = 3 = 0x3
        |ucflag = 0 = 0x0
        |  cmdtp = 0x9FFD1F18
        |
        |...
        | * executing a command.
        | *
        | * @param cmdtp         Pointer to the command to execute
        | * @param flag          Some flags normally 0 (see CMD_FLAG_.. above)
        | * @param argc          Number of arguments (arg 0 must be the command text)
        | * @param argv          Arguments
        | * @return 0 if command succeeded, else non-zero (CMD_RET_...)
        | */
        |static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        |{
        |        int result;
        |
        |        result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
        |                rc = cmd_call(cmdtp, flag, argc, argv);
    -007|run_pipe_real(inline)
    -007|run_list_real(inline)
    -007|run_list_real(
        |  ?)
        |#esave_name = 0x0
        |#dlist = 0x0
        |#esave_list = 0x0
        |  flag_rep = 0 = 0x0
        |#ircode = 0 = 0x0
        |stflag_skip = 1 = 0x1
        |  flag_restore = 0 = 0x0
        |stif_code = 0 = 0x0
        |{ next_if_code = 0 = 0x0
        |  skip_more_in_this_rmode = RES_XXXX = 11 = 0x0B
        |  pi = 0x9DF548B0
        |  save_name = 0x0
        |  save_list = 0x0
        |#irpipe = 0x0
        |  flag_rep = 0 = 0x0
        |cmflag_restore = 0 = 0x0
        |cmif_code = 0 = 0x0
        |  next_if_code = 0 = 0x0
        |  rmode = RES_NONE = 0 = 0x0
        |  pi = 0x9DF548B0
        |  child = 0x9DF549A0
        |
        |                }
        |                /* Process the command */
        |                return cmd_process(flag, child->argc, child->argv,
    -008|run_list(inline)
    -008|parse_stream_outer(
        |    inp = 0x9DF3876C,
        |  . flag = 2 = 0x2)
        | *ctx = (child = 0x9DF54A08, list_head = 0x9DF548B0, pipe = 0x9DF549F0, w = RES_NONE = 0 = 0x0, old_flag = 0 = 0x0, stack = 0x0, type = 2 = 0x2)
        | *temp = (data = 0x9DF548C8, length = 0 = 0x0, maxlen = 100 = 0x64, quote = 0 = 0x0, nonnull = 0 = 0x0)
        | *rcode = 0 = 0x0
        | *pi = 0x9DF548B0
        |
        |}
        |
        |/* Select which version we will use */
        |static int run_list(struct pipe *pi)
        |{
        |        int rcode=0;
        |#ifndef __U_BOOT__
        |        if (fake_mode==0) {
        |#endif
        |                rcode = run_list_real(pi);
    -009|parse_file_outer()
        |rurcode = 1155575808 = 0x44E0B000
        |  input = (p = 0x9FFD3BEA, __promptme = 1 = 0x1, promptmode = 2 = 0x2, get = 0x9FF74D95, peek = 0x9FF74FE5)
        |
        |#endif
        |        rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
    -010|cli_loop()
        |
        |}
        |#endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
        |
        |void cli_loop(void)
        |{
        |#ifdef CONFIG_HUSH_PARSER
        |        parse_file_outer();
    -011|bootstage_mark_name(inline)
    -011|main_loop()
        |  s = 0x9DF50960
        |
        |        cli_loop();
    -012|run_main_loop()
        |  return = 1155575808 = 0x44E0B000
        |
        |        for (;;)
        |                main_loop();
        |        return 0;
        |}
        |
        |/*
    -013|initcall_run_list(
        |    init_sequence = 0x9FFCBF54)
        |  init_fnc_ptr = 0x9FFCBFEC
        | *ret = 1155575808 = 0x44E0B000
        |
        |                if (ret) {
    -014|board_init_r(
        |  ?,
        |  ?)
        |
        |#endif
        |
        |        if (initcall_run_list(init_sequence_r))
        |                hang();
        |
        |        /* NOTREACHED - run_main_loop() does not return */
        |        hang();
    -015|board_init_r(
        |  rsnew_gd = 0x44E0B000,
        |  rcdest_addr = 1 = 0x1)
        |
        |}
        |
     ---|end of frame
    

  • Thank you for reply.
    Why do you use Lauterbach ?
    I'd like to use CCS as shown in this video ( https://training.ti.com/linux-board-porting-series-module-7-debugging-u-boot-jtag-ccs ) .

  • Hello,
    I have only possession of Lauterbach T32 JTAG debugger, but not CCS one.
    But the two attached files in my last post "should" apply to any JTAG debugger.
    For example, augments *i2c_base, ip_rev, speed, *waitdely are passed into __omap24_i2c_setspeed() via ARM registers R1, R2, R3, R4 as shown in the attached scrren-shot file.
    Have you tried the same bkpt using CCS on your set-up? If yes, can we capture a similar screen-shot?

    -000|__omap24_i2c_setspeed(
        |    i2c_base = 0x44E0B000,
        |    ip_rev = 1 = 0x1,
        |    speed = 400000 = 0x00061A80,
        |    waitdelay = 0x9DF54A38)

    Best,

    -Hong

  • Thank you for reply.
    I'm not familiar with either u-boot debugging or Lauterbach or CCS, so I don't know what bkpt means. Could you please teach me that ?

    By the way, I set a hardware breakpoint at __omap24_i2c_setspeed(), but program didn't stopped.
    So, I set a hardware breakpoint at fs_set_blk_dev(). After stopped, I captured CCS window as shown in Fig.1.
    Can you find any mistakes or wrong settings ?

    Fig.1

  • Hello,
    Are you trying to JTAG debug SPL or u-boot?
    The example in my reply is from debugging u-boot, where relocating u-boot symbol might be needed.
    I'm attaching two PDFs:
    - SPL boot flow,
    - u-boot boot flow, where you'll find some info on u-boot relocation.

    JTAG debugging with CCS links:
    software-dl.ti.com/.../Apps-SPL-Debug.html
    software-dl.ti.com/.../Apps-Load-in-CCS.html
    Best,
    -Hong

    31562.spl_boot_flow_v1.pdf

    u-boot_boot_flow.pdf

  • Thank you for reply.
    I'm debugging both SPL and u-boot by CCS.
    I can watch variables during SPL debugging without any problem.
    But, I can't watch any variables during u-boot debugging.
    As the link you wrote above mentioned, I have always tried u-boot symbol relocation. Also, in the TI's training video, it was emphasized to relocate u-boot symbol which was displayed by bdinfo command.

    Is there additional step other than u-boot symbol relocation ?

  • Hello,
    Let me recap my steps:
    - boot AM335x GP EVM from SD card;
    - stop @u-boot prompt;
    - attach T32 JTAG debugger, where "attach" is non-intrusive for u-boot running OR no HW board reset.
    - load u-boot symbol file with "relocation"
    - setup breakpoint (bkpt) @ the entry of __omap24_i2c_setspeed();
    - run "i2c dev 0" cmd @u-boot prompt;
    - The bkpt will be hit.

    => The attached two files in my first reply!
    Best,
    -Hong

  • Hello,
    Program stopped at hardware breakpoint as you mentioned above.
    But, any arguments (i2c_base, ip_rev, speed, or waitdelay) were not be displayed when I hovered over these variables as shown in the figure below.

    By the way, I'd like to tell you that it seems not possible that CCS attach the target CPU. I can't find "attach" button in CCS window.
    So I tried "Connect Target" button. This button seems to operate HW board reset automatically.

  • Hello,
    Your attached screen-shot @bkpt @entry of __omap24_i2c_setspeed() looks good to me.
    The arguments *i2c_base, ip_rev, speed, *waitdely are passed into __omap24_i2c_setspeed() via ARM registers R0, R1, R2, R3
    They're matching the screen-shot and the call flow in my first reply.
    Best,
    -Hong

  • Hello,
    I understood that the arguments (*i2c_base, ip_rev, speed, *waitdely) were stored in R0-R3 registers respectively.
    Can you investigate why CCS didn't display these arguments' values when hovering over them ?

  • Hello,
    I'm able to see "*i2c_base, ip_rev, speed, *waitdely" in T32 "watch window" as shown.

    I'd think the same would be possible in CCS.
    I'll check with my colleague on CCS.
    Best,
    -Hong

  • Naoto,

    If you add the variable names (like speed) to the "Expressions" view what does it say there?  Does it show a value or say "Identifier not found"?

    Regards,

    John

  • Hello,

    I tried that.
    It showed "Identifier not found" as the figure below.

  • If you step a few instructions into the function, does that cause the "Identifier not found" diagnostics to go away?

    Thanks and regards,

    -George

  • Hello,
    I stepped some instructions to 0x8ff89fd0.
    Then, the value of local variable "fclk" was displayed as the figure below.
    But, the values of other variables were not displayed. It remained "Identifier not found".

  • Naoto,

    Here is a link to the latest CCSv11.0 release candidate.  It has some improvements for debugging GCC generated applications.  We could try this to see if it makes a difference.

    https://software-dl.ti.com/ccs/esd/CCSv11/CCS_11_0_0/exports/CCS11.0.0.00011_win64.zip

    Regards,

    John

  • Hello,
    I tried CCS v11.0 you mentioned above.
    The result was the figure below.
    The value of local variable "fclk" was displayed, but the values of other
    local variables were not displayed.
    Additionally, the value of static variables "reg_map_ip_v1" and "reg_map_ip_v2" were displayed, compared to CCS 7.3.0 I used previously.

    By the way, CCS v11.0 installation process was frozen as the figure below. I think that it was no problem because "Installation completed" message was displayed.

  • Naoto,

    Well it is good to see that CCSv11 is a bit better.  That is probably the best we can do.  In CCSv11 we are using an open source component from LLVM to read the debug symbol information from GCC generated executables.

    Hong seemed to have more information available when using Lauterbach.  Ideally we would get him to try CCS on the same machine, board and symbol files to see if it is an environment issue or just something that is better supported by Lauterbach.

    John

  • Hello,
    I'm using TMDSSK3358 and the latest SDK.
    (ti-processor-sdk-linux-am335x-evm-07.03.00.005-Linux-x86-Install.bin)

    Though I added some modifications into SPL and u-boot, this issue can be reproduced using default SPL and u-boot.
    Also, I modified Rules.make to suit my Linux environment, and config file remain default. ( UBOOT_MACHINE=am335x_evm_config ).

    Can you reproduce this issue using CCS and investigate further ?

  • Uegaki-san,

    We are working with Hong to see if we can reproduce the issue locally within TI. I will keep you posted of our progress.

    Thank you

    ki

  • I will need to set up a similar environment and will try to reproduce this locally on my end. My apologies for the delay.

    ki

  • Just a quick update, I believe I have the necessary setup now and I will try to reproduce this shortly.

  • Update: I can reproduce the issue using CCSv11 on Ubuntu 18.04 with my AM335x EVM.

  • I filed a bug for this issue. Tracking ID: https://sir.ext.ti.com/jira/browse/EXT_EP-10595

    Thanks

    ki

  • Thank you for reply.
    I don't know CCS bug fixing process very well.
    If EXT_EP-10595 is fixed, will it be included in CCSv11 release ?
    Anyway, I think that this issue should be checked as closed.

  • If EXT_EP-10595 is fixed, will it be included in CCSv11 release ?

    CCSv11 was released a few days ago so any fix will be in a subsequent version. The engineers need to analyze the bug further before they can comment on when a fix will be available.

    Thank you

    ki