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

How can a program detect the uVision simulator?

Is there a way for a program to know if it's executed under the simulator and not on an actual CPU?

Parents
  • So, if it is not confidential, it would be nice if you can provide Why/Why-Not.

    Well, it was the choice of our hardware engineers :) I'm not sure, but it has something to do with the size of our device and their not being able to find room for the connectors on the boards :) As a matter of fact, we have two LPC chips on one board and more on others, and we can't even program them separately. We communicate with one of them via CAN and it in turn programs the others using ISP...

Reply
  • So, if it is not confidential, it would be nice if you can provide Why/Why-Not.

    Well, it was the choice of our hardware engineers :) I'm not sure, but it has something to do with the size of our device and their not being able to find room for the connectors on the boards :) As a matter of fact, we have two LPC chips on one board and more on others, and we can't even program them separately. We communicate with one of them via CAN and it in turn programs the others using ISP...

Children
  • When there is lack of room for a connector, it's still often possible to just get a few test points on the board and then you manually solder wires to get a debugging interface. With good solder skills, the test points can be made very small and very close together.

    So in the end, I find it very strange to not be able to make the boards capable of JTAG-debugging.

    But there is another, very easy, option - solder a JTAG interface directly on the processor pins. Spend 30 minutes and you have a board with JTAG debugging. Way better than simulation and you can finally debug real code without strange code stubs that you wouldn't want in a final release version.

  • Alright. Just in case someone is still interested in the topic, I'd like to offer a working cross-platform example of how the simulator can be detected using a debug script. Kudos goes to Chad Clendening and Per Westermark for the idea.

    This code works on both the ARM and the 8051 simulators, with slightly different debug scripts. I now don't have all the necessary hardware to test the code on it, but I hope it works on it just as good :) Anyway, I would appreciate it if someone would check that out :)

    /* sim-detect.c */
    
    #include <stdio.h>
    #include <string.h>
    
    #if defined(__arm__)
    
    /* This is here only to print a message over UART. In the IDE it will show up
       in a Serial Window. */
    
    #include <lpc21xx.h>
    
    #define VPB_CLOCK 12000000
    #define BAUD_RATE 9600
    
    int sendchar(int ch) {
    
            while (!(U0LSR & 0x20))
                    ;
    
            return (U0THR = ch);
    }
    
    /* ------------------------------------------------------------------------- */
    
    int getkey(void) {
    
            while (!(U0LSR & 0x01))
                    ;
    
            return U0RBR;
    }
    
    /* ------------------------------------------------------------------------- */
    
    struct __FILE {
            int handle;
    };
    
    /* ------------------------------------------------------------------------- */
    
    int fputc(int ch, FILE *f) {
    
            return sendchar(ch);
    }
    
    /* ------------------------------------------------------------------------- */
    
    void _sys_exit(int return_code) {
    
            for (;;)
                    ;
    }
    
    /* ------------------------------------------------------------------------- */
    
    #elif defined(__C51__)
    
    #include <reg51.h>
    
    #endif
    
    /* Attention! These memory address values were chosen for demonstration
       purposes only. They may be incompatible with your particular memory
       layout. */
    
    #if defined(__arm__)
    
    #define SIM_DETECTOR_ATTR       __attribute__((section(".ARM.__at_0x40000000")))
    
    #elif defined(__C51__)
    
    #define SIM_DETECTOR_ATTR       _at_ 0x30
    
    #else
    
    #define SIM_DETECTOR_ATTR
    
    #endif
    
    volatile unsigned char sim_detector SIM_DETECTOR_ATTR;
    
    int main(void) {
    
            /* set up UART0 to see the detection message */
    
    #if defined(__arm__)
    
            PINSEL0 = 0x00000005;
            U0LCR = 0x83;
            U0DLL = (VPB_CLOCK/16/BAUD_RATE) & 0xFF;
            U0DLM = ((VPB_CLOCK/16/BAUD_RATE) >> 8) & 0xFF;
            U0LCR = 0x03;
    
    #elif defined(__C51__)
    
            SCON  = 0x50;
            TMOD |= 0x20;
            TH1   = 213;
            TR1   = 1;
            TI    = 1;
    
    #endif
    
            sim_detector = 0x55;
    
            if (sim_detector == 0xAA)
                    puts("SIMULATOR DETECTED");
            else
                    puts("SIMULATOR NOT DETECTED");
    
            return 0;
    }
    
    

    The debug script for the ARM:

    /* debug-arm.ini */
    signal void sim_detect(unsigned long adr) {
            unsigned char val;
            while (1) {
                    /* wait for write access */
                    wwatch(adr);
                    /* read value */
                    val = _RBYTE(adr);
                    /* uncomment the line below if you want to see sim_detector values */
                    // printf("sim_detector = %X\n", val);
                    /* change value */
                    val = ~val;
                    /* write value back */
                    _WBYTE(adr, val);
            }
    }
    
    
    sim_detect(0x40000000);

    The debug script for the 8051:

    /* debug-c51.ini */
    signal void sim_detect(unsigned long adr) {
            unsigned char val;
            while (1) {
                    /* wait for write access */
                    wwatch(adr);
                    /* read value */
                    val = _RBYTE(adr);
                    /* uncomment the line below if you want to see sim_detector values */
                    // printf("val = %X\n", val);
                    /* change value */
                    val = ~val;
                    /* write value back */
                    _WBYTE(adr, val);
            }
    }
    
    sim_detect(D:0x30);
    

  • By the way - never let hardware engineers run the show all by themselves. Always make sure that there are one or more skilled sw guys involved, and that it is 100% clear that the total quality of the product depends on the ability to test both the hardware and the software. And that a JTAG interface isn't just an optional method of programming the processors but an excellent way to validate the prototype hardware by allowing the pins to be wiggled etc.