jazz 209 Posted September 30, 2012 Share Posted September 30, 2012 This is for assembler programmers, way of debugging based on software without any hardware tools (only uC). So if you are programming MSP430 with C, playing in (launchpad) lego world, this is not for you. I will not publish complete source here, but will introduce idea, and help someone to build it's own version (not only for MSP430). I was working (before MSP430) on some other uC that don't have debugging interface (like MSP430), and there is no nice way for checking the code. There was (for some uC) debugging based on inserting software layer under the user program, or only adding some software around breakpoints. And than this special software inside uC was communicating with debugging hardware, or only with PC application. Big minus for debugging on this (only possible) way was in losing some flash/ram memory blocks, original vector table or registers, because debugger was using them for itself. All uC have (at least one) uart port, or it can be created (by software) if not exist. My idea was to use one uart for uC/PC main application, and another uart for uC/PC debugging. Debugging function are placed in separate file and just in lined in main assembler source (#include "dbg_uart.s43"). If debugging in main file is enabled (#define DBG_UART) also will be enabled all debugging functions (#ifdef DBG_UART). If debugging in main file is disabled, produced program (final release) will be in original form, without any debugging part. I made mine own BLS version, and I use it not only for flashing, but also for standard MSP430/PC uart communication when I need it. It is based on MAX3243E (SOIC) from TI, and placed inside DB9 connector. RobG 1 Quote Link to post Share on other sites
jazz 209 Posted September 30, 2012 Author Share Posted September 30, 2012 All debugging functions for working use only stack, average about 10 words. For today uC's (MSP430F5xx) this is not big issue. State after calling debugging functions must be the same like before call, all registers must be unchanged (except R15, that is used as input/output parameter for debugging functions). Of course, uart used for debugging can't be used in main application for something else. Application on PC side is simple. After opening serial port it start reading from uart. Always read just one byte, and if the reading failed (timeout) read again, and again... (forever). Display received character on CMD and save it in log file. After receiving CR create new line. There is no need to close port during flashing/reseting uC. Here is assembler source with debugging functions: C932 C932 B01200C0 call #DbgCR C936 C936 B01228C0 call #DbgStr C93A 50726F677261* db 'Program Begin', 0 C948 B01200C0 call #DbgCR C94C C94C 3A403412 mov.w #01234h, R10 C950 3B404523 mov.w #02345h, R11 C954 3C405634 mov.w #03456h, R12 C958 3D406745 mov.w #04567h, R13 C95C 3E407856 mov.w #05678h, R14 C960 3F408967 mov.w #06789h, R15 C964 C964 B012CAC2 call #DbgRegs C968 B01200C0 call #DbgCR C96C C96C B012D4C1 call #DbgPC C970 B01200C0 call #DbgCR C974 C974 3F403930 mov.w #012345, R15 C978 B01272C1 call #DbgWordDec C97C C97C B01228C0 call #DbgStr C980 202B2000 db ' + ', 0 C984 C984 0E4F mov.w R15, R14 C986 C986 3F40A05B mov.w #023456, R15 C98A B01272C1 call #DbgWordDec C98E C98E B01228C0 call #DbgStr C992 203D2000 db ' = ', 0 C996 C996 0F5E add.w R14, R15 C998 B01272C1 call #DbgWordDec C99C B01200C0 call #DbgCR C9A0 C9A0 3012434B push.w #04B43h C9A4 30125441 push.w #04154h C9A8 30122053 push.w #05320h C9AC 30124F4E push.w #04E4Fh C9B0 B01216C2 call #DbgStack C9B4 B01200C0 call #DbgCR C9B8 3F41 pop.w R15 C9BA 3F41 pop.w R15 C9BC 3F41 pop.w R15 C9BE 3F41 pop.w R15 C9C0 C9C0 22C3 clrz C9C2 B01266C2 call #DbgSR C9C6 B01200C0 call #DbgCR C9CA C9CA B01228C0 call #DbgStr C9CE 537472696E67* db 'String', 0, 0 C9D6 B01200C0 call #DbgCR C9DA C9DA 22D3 setz C9DC B01266C2 call #DbgSR C9E0 B01200C0 call #DbgCR C9E4 C9E4 3F400ACA mov.w #Mem, R15 C9E8 B01270C3 call #DbgMem C9EC B01200C0 call #DbgCR C9F0 C9F0 B01228C0 call #DbgStr C9F4 50726F677261* db 'Program End', 0 CA00 B01200C0 call #DbgCR CA04 CA04 B01200C0 call #DbgCR CA08 CA08 FF3F jmp $ CA0A CA0A 2E4D656D6F72*Mem db '.Memory.', 0 CA13 Here is log file on PC side: [30.9.2012 19:10:11] [30.9.2012 19:10:14] Program Begin [30.9.2012 19:10:14] R4:FFFF R5:FFFF R6:0002 R7:FFFF R8:245C R9:0000 [30.9.2012 19:10:14] R10:1234 R11:2345 R12:3456 R13:4567 R14:5678 R15:6789 [30.9.2012 19:10:14] PC:C970 [30.9.2012 19:10:14] 12345 + 23456 = 35801 [30.9.2012 19:10:14] SP:33F8 33F8: 4F 4E 20 53 54 41 43 4B ; ON STACK [30.9.2012 19:10:14] SR:010C 0000000100001100 [30.9.2012 19:10:14] String [30.9.2012 19:10:14] SR:010E 0000000100001110 [30.9.2012 19:10:14] CA0A: 2E 4D 65 6D 6F 72 79 2E ; .Memory. [30.9.2012 19:10:14] Program End [30.9.2012 19:10:14] RobG 1 Quote Link to post Share on other sites
jazz 209 Posted September 30, 2012 Author Share Posted September 30, 2012 I made USB CDC (for MSP5xx) in assembler, and without this kind of debugging it will be mission impossible. Here is log of enumeration process: [30.9.2012 17:38:25] --- Reset USBIFG 80 ---[30.9.2012 17:38:26] --- Reset USBIFG 80 ---[30.9.2012 17:38:27] --- Reset USBIFG 80 ---[30.9.2012 17:38:28] --- Setup USBIFG 04 USBSUBLK 2380: 80 06 00 01 00 00 40 00 ; Quote Link to post Share on other sites
jazz 209 Posted September 30, 2012 Author Share Posted September 30, 2012 At the beginning of main source is something like this: #define DBG_UART ... #ifdef DBG_UART #include "dbg_uart.s43" #endif Before starting point in main program is debugging uart configuration (for MSP430F5510): #ifdef DBG_UART bis.b #(BIT4 + BIT5), &P4SEL ; P4.4/P4.5 = USCI_A1 TXD/RXD bis.b #UCSWRST, &UCA1CTL1 ; Put USCI state machine in reset bis.b #UCSSEL_2, &UCA1CTL1 ; SMCLK ; 25 MHz 460800 bps mov.b #036h, &UCA1BR0 mov.b #000h, &UCA1BR1 bis.b #(UCBRS_2 + UCBRF_0), &UCA1MCTL bic.b #UCSWRST, &UCA1CTL1 ; Initialize USCI state machine #endif Later, debugging somewhere in main program: #ifdef DBG_UART call #DbgRegs call #DbgCR #endif Quote Link to post Share on other sites
jazz 209 Posted September 30, 2012 Author Share Posted September 30, 2012 At the begining of "dbg_uart.s43" is uart selection: ;-------------------------------------------------------------------- ; Uart used for debugging ;-------------------------------------------------------------------- UartIF equ UCA1IFG UartBuff equ UCA1TXBUF And simplest function is: ;-------------------------------------------------------------------- ; DbgCR ; 10 13 -> Uart ;-------------------------------------------------------------------- DbgCR push.w SR DbgCR1 bit.b #UCTXIFG, &UartIF jnc DbgCR1 mov.b #00Ah, &UartBuff DbgCR2 bit.b #UCTXIFG, &UartIF jnc DbgCR2 mov.b #00Dh, &UartBuff pop.w SR ret Bytes are directly sent to uart, and all registers are unchanged (except debuging uart registers). Quote Link to post Share on other sites
jazz 209 Posted October 1, 2012 Author Share Posted October 1, 2012 For all this (PC/uC uart connection) we need some kind of hardware, RS232 chip and USB/uart bridge (BTW, PL2303HXD is the best one, it works with any baud rate under 12 Mbps, for example: 123456 bps, 654321 bps...) if PC is without standard uart. But why? MSP430F55x have USB, so debugging can go by USB (CDC)? Yes, but in this case things are become more complicated. If the main application also use USB, then composite device must be configured/enumerated with #ifdef statements. If release version (without debugging) is generated, it must be in original form without any debugging part. Quote Link to post Share on other sites
jazz 209 Posted October 1, 2012 Author Share Posted October 1, 2012 At the beginning of main source is something like this: #define DBG_USB ... #ifdef DBG_USB #include "dbg_usb.s43" #endif PC logging application can't be open all the time (like with uart), because during flashing/restarting uC, virtual serial port (CDC used for debugging) will disappear. After uC is started, and enumeration is done (CDC created), uC must wait (or need to be triggered by) logging application on PC. It's enough just to send one byte to uC, for starting. End point 2 is used for debugging. #ifdef DBG_USB WaitByteFromPC bit.b #NAK, &USBOEPBCTX_2 jnc WaitByteFromPC mov.b #0, &USBOEPBCTX_2 #endif Name of debugging functions is the same like with uart, so there is no need to change something in the main program (just change/adjust #ifdef statement) for switching between uart/USB debugging. #ifdef DBG_USB call #DbgRegs call #DbgCR #endif Quote Link to post Share on other sites
jazz 209 Posted October 1, 2012 Author Share Posted October 1, 2012 At the begining of "dbg_usb.s43" is end point selection: ;-------------------------------------------------------------------- ; Input Endpoint for debugging ;-------------------------------------------------------------------- IEBuf equ USBIEPBBAX_2 IEBufCnt equ USBIEPBCTX_2 IEBuf0 equ IEBuf + 0 IEBuf1 equ IEBuf + 1 IEBuf2 equ IEBuf + 2 IEBuf3 equ IEBuf + 3 IEBuf4 equ IEBuf + 4 IEBuf5 equ IEBuf + 5 IEBuf6 equ IEBuf + 6 IEBuf7 equ IEBuf + 7 IEBuf8 equ IEBuf + 8 IEBuf9 equ IEBuf + 9 And simplest function is: ;-------------------------------------------------------------------- ; DbgCR ; 10 13 -> Ser ;-------------------------------------------------------------------- DbgCR push.w SR mov.b #00Ah, &IEBuf0 mov.b #00Dh, &IEBuf1 mov.b #2, &IEBufCnt DbgCR1 bit.b #NAK, &IEBufCnt jnc DbgCR1 pop.w SR ret Difference in sending data, is that with uart byte by byte is going out, and with USB all bytes can be stored first in buffer, and than sent together. Result of log application on PC side is the same in both (uart/USB) cases. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.