This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

User defined functions in uVision3

Has anyone ever seen an authoritative document on using
debug functions in uVision3?  It could be a powerful tool if
I knew how to use it, but what little information I have
come across is scattered across 2 hardcopy manuals, a bit
more in the help file system, and smatterings in the Keil
Knowledgebase.

Here are clues, not documented anywhere, that I have
discovered by trial and error:
  - If the last line of a .ini file containing function
    definitions does not end in a CR/LF, you get a "syntax
    error".
  - The "Breakpoint Set (BS), and "Go" (GO) commands may be
    executed from the command line, but not inside a
    function.
  - If you access program variables from the function, you
    must halt execution at a point in the program where
    they are all in scope before you load the function with
    an "include" command.  Otherwise you get another "syntax
    error."
  - When you define and/or when you invoke a function, you
    must terminate its name with a pair of parentheses.
    When you "kill" the function, you must omit the
    parentheses. Otherwise, you get another one of those
    ubiquitous "syntax errors".
  - It could be that everything is a syntax error in this
    domain.  The messages are that useful.              :-}

Perhaps if we all pool our insights, we will have a running
start on a manual.
============================================================
Gary Lynch           |   To send mail, no$pam in domain name
lynchg@no$pam.com    |   must be changed to stacoenergy.

Parents
    1. Although it is technically possible to create a user- defined function from the 'Output Window-Command' page of uVision 3, it is almost never worth the hassle. You are better off saving your definition to a command file and read the command file in with the INCLUDE command in the 'Output Window-Command' page.
    2. Syntax of user-defined function definition is very close to C, except:
      • The definition is preceded by the key word "FUNC",
      • Function parameter names may not overlap any variable name in the application, including automatics. This condition is case-insensitive.
      • There are no function prototypes, and forward references are not allowed. Therefore if a user-defined function calls another function defined in same command file:
                  func1()
                  +--func2()
                  |  +--func3()
                  func4()
        

        they must be declared in inverse call order.

                    FUNC void func4(void) {
                      ....
                    }
                    FUNC void func3(void) {
                      ....
                    }
                    FUNC void func2(void) {
                      ....
                      func3();
                    }
                    FUNC void func1(void) {
                      ....
                      func2();
                      func4();
                    }
        
      • Types are spelled slightly differently:
                  - BIT     - INT     - UINT
                  - CHAR    - LONG    - ULONG
                  - FLOAT   - UCHAR   - VOID
        

        Case is not supposed to matter, but I have only tried the upper-case versions.

    3. The most effective user functions output data to a file on your workstation using the "log" command. To reduce wear & tear on my (biological) memory, I use the same name for the script file, the function it defines, and the log file the function creates--just change the extension. The default extension for a command file is .ini. The following simple example uses these principles to grab a "snapshot" of the I/O port SFRs of the Silicon Labs C8051F04x MCUs:
            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
            /*                                                         */
            /* dumpIoPorts.ini                                         */
            /* Version of 08/06/06                                     */
            /*                                                         */
            /* Debug script to dump content of all I/O port config     */
            /* SFRs                                                    */
            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
      
            FUNC void dumpIoPorts(void) {
              INT ri, ci;
      
              exec("log > dumpIoPorts.log");
      
            /* + + + + + + + + + + + + + + + + */
            /*                                 */
            /*  Output template of SFR dump:   */
            /*                    Input Output */
            /*        Port  Data  Mode  Mode   */
            /*        ----  ----  ----  ----   */
            /*         P0    00    ..    00    */
            /*         P1    00    00    00    */
            /*         P2    00    00    00    */
            /*         P3    00    00    00    */
            /*         P4    00    ..    00    */
            /*         P5    00    ..    00    */
            /*         P6    00    ..    00    */
            /*         P7    00    ..    00    */
            /* + + + + + + + + + + + + + + + + */
      
              printf("            Input Output\n");
              printf("Port  Data  Mode  Mode\n");
              printf("----  ----  ----  ----\n");
      
              printf(" P0    %02X    ..    %02X\n",   P0, P0MDOUT);
              printf(" P1    %02X    %02X    %02X\n", P1, P1MDIN, P1MDOUT);
              printf(" P2    %02X    %02X    %02X\n", P2, P2MDIN, P2MDOUT);
              printf(" P3    %02X    %02X    %02X\n", P3, P3MDIN, P3MDOUT);
              printf(" P4    %02X    ..    %02X\n",   P4, P4MDOUT);
              printf(" P5    %02X    ..    %02X\n",   P5, P5MDOUT);
              printf(" P6    %02X    ..    %02X\n",   P6, P6MDOUT);
              printf(" P7    %02X    ..    %02X\n",   P7, P7MDOUT);
      
              exec("log off");
            }
      

      [continued in part 3]

Reply
    1. Although it is technically possible to create a user- defined function from the 'Output Window-Command' page of uVision 3, it is almost never worth the hassle. You are better off saving your definition to a command file and read the command file in with the INCLUDE command in the 'Output Window-Command' page.
    2. Syntax of user-defined function definition is very close to C, except:
      • The definition is preceded by the key word "FUNC",
      • Function parameter names may not overlap any variable name in the application, including automatics. This condition is case-insensitive.
      • There are no function prototypes, and forward references are not allowed. Therefore if a user-defined function calls another function defined in same command file:
                  func1()
                  +--func2()
                  |  +--func3()
                  func4()
        

        they must be declared in inverse call order.

                    FUNC void func4(void) {
                      ....
                    }
                    FUNC void func3(void) {
                      ....
                    }
                    FUNC void func2(void) {
                      ....
                      func3();
                    }
                    FUNC void func1(void) {
                      ....
                      func2();
                      func4();
                    }
        
      • Types are spelled slightly differently:
                  - BIT     - INT     - UINT
                  - CHAR    - LONG    - ULONG
                  - FLOAT   - UCHAR   - VOID
        

        Case is not supposed to matter, but I have only tried the upper-case versions.

    3. The most effective user functions output data to a file on your workstation using the "log" command. To reduce wear & tear on my (biological) memory, I use the same name for the script file, the function it defines, and the log file the function creates--just change the extension. The default extension for a command file is .ini. The following simple example uses these principles to grab a "snapshot" of the I/O port SFRs of the Silicon Labs C8051F04x MCUs:
            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
            /*                                                         */
            /* dumpIoPorts.ini                                         */
            /* Version of 08/06/06                                     */
            /*                                                         */
            /* Debug script to dump content of all I/O port config     */
            /* SFRs                                                    */
            /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
      
            FUNC void dumpIoPorts(void) {
              INT ri, ci;
      
              exec("log > dumpIoPorts.log");
      
            /* + + + + + + + + + + + + + + + + */
            /*                                 */
            /*  Output template of SFR dump:   */
            /*                    Input Output */
            /*        Port  Data  Mode  Mode   */
            /*        ----  ----  ----  ----   */
            /*         P0    00    ..    00    */
            /*         P1    00    00    00    */
            /*         P2    00    00    00    */
            /*         P3    00    00    00    */
            /*         P4    00    ..    00    */
            /*         P5    00    ..    00    */
            /*         P6    00    ..    00    */
            /*         P7    00    ..    00    */
            /* + + + + + + + + + + + + + + + + */
      
              printf("            Input Output\n");
              printf("Port  Data  Mode  Mode\n");
              printf("----  ----  ----  ----\n");
      
              printf(" P0    %02X    ..    %02X\n",   P0, P0MDOUT);
              printf(" P1    %02X    %02X    %02X\n", P1, P1MDIN, P1MDOUT);
              printf(" P2    %02X    %02X    %02X\n", P2, P2MDIN, P2MDOUT);
              printf(" P3    %02X    %02X    %02X\n", P3, P3MDIN, P3MDOUT);
              printf(" P4    %02X    ..    %02X\n",   P4, P4MDOUT);
              printf(" P5    %02X    ..    %02X\n",   P5, P5MDOUT);
              printf(" P6    %02X    ..    %02X\n",   P6, P6MDOUT);
              printf(" P7    %02X    ..    %02X\n",   P7, P7MDOUT);
      
              exec("log off");
            }
      

      [continued in part 3]

Children
No data