- ARM microcontroller development
- Some notes about developing software for ARM microcontrollers on
- linux, more specifically:
- - Atmel AT91SAM7 (ARM7TDMI)
- - OpenOCD
- - Olimex ARM-USB-OCD
- Entry: ARM JTAG
- Date: Thu Aug 19 17:50:41 CEST 2010
- With my recent experience using gdb + gdbserver on an Atmel AT91SAM7
- using a closed Segger JLink[4] interface I'm wondering what tools I
- should get to be able to use all full open source chain.
- 1. How to get my ET-ARM STAMP LPC2110[1] board to work with JTAG?
- I.e. how does the plugin board[2] connect to the stamp board?
- 2. What JTAG interface to use to get maximum support from OpenOCD[3]?
- What are the different JTAG features some have and some don't? How
- do all the pieces fit together? (uC JTAG + gdbserver).
- Olimex[5] has several.
- 3. Can this work on a DIP-package small uC? Probably not PIC as it
- has an incompatible proprietary debugging interface (one reason to
- stop using it..), but maybe AVR? I can only find AVR32 links..
- Does AVR8 have JTAG actually[6]?
- First I wonder, is there a natural way to map a 2-way serial byte
- stream to a JTAG stream? JTAG is SPI, right?
- Then: is there any monitor code running on the target to support
- JTAG/gdbserver functionality that is not implemented in hardware?
- Ok, the basic idea as explained in Dominic Rath's thesis[8].
- On-chip debugging allows external control over the uC as opposed to
- sub-based debugging which would use a monitor and some kind of
- interrupt mechanis, i.e. a serial port.
- ARM7 and ARM9 have halt mode debugging, where the core is completely
- stopped. Both cores support 2 comparators that allow to break on
- instruction fetches or data access.
- Disadvantage of stub-based programming for flash uC is setting of
- breakpoints (as opposed to code in RAM). HW debug can set hardware
- breakpoints.
- [1] http://www.futurlec.com/ET-ARM_Stamp.shtml
- [2] http://www.futurlec.com/ET-ARM_Stamp_Board.shtml
- [3] http://openocd.berlios.de/web/
- [4] http://www.segger.com/cms/jlink.html
- [5] http://olimex.com/dev/index.html
- [6] http://www.scienceprog.com/build-your-own-avr-jtagice-clone/
- [7] http://sourceforge.net/apps/mediawiki/urjtag/index.php?title=Main_Page
- [8] http://openocd.berlios.de/thesis.pdf
- Entry: JTAG for LPC2119
- Date: Fri Aug 20 16:59:45 CEST 2010
- dir signal pin port
- --------------------
- <- TRST 20 1.31
- <- TMS 52 1.30
- <- TCK 56 1.29
- <- TDI 60 1.28
- -> TDO 64 1.27
- -> RTCK 24 1.26
- Entry: OpenOCD on Olimex ARM-USB-OCD
- Date: Wed Sep 15 14:47:30 CEST 2010
- # Starting with "apt-get install openocd" I get openocd which seems to
- # support the FT2232 (see openocd -c interface_list).
- # Scripts are relative to /usr/share/openocd/ in my install.
- # This also seems to have config support for an the Olimex SAM7-EX256
- # board[3]. scripts/board/olimex_sam7_ex256.cfg
- # The script only sources this script:
- scripts/target/sam7x256.cfg
- # I have the SAM7-H256 board[2] connected, so it should just work.
- # For the programmer Olimex ARM-USB-OCD it seems these scripts are used:
- scripts/interface/olimex-arm-usb-ocd-h.cfg
- scripts/interface/olimex-arm-usb-ocd.cfg
- # To use these scripts (had to use sudo -> need to fix perms).
- $ cd /usr/share/openocd/scripts
- $ openocd --file interface/arm-usb-ocd.cfg --file target/sam7x256.cfg
- Open On-Chip Debugger 0.4.0 (2010-02-23-16:59)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.berlios.de/doc/doxygen/bugs.html
- srst_only srst_pulls_trst srst_gates_jtag srst_open_drain
- Info : clock speed 6000 kHz
- Info : JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
- Info : Embedded ICE version 1
- Info : sam7x256.cpu: hardware has 2 breakpoint/watchpoint units
- # The default port is 3333.
- $ arm-eabi-gdb
- (gdb) target remote localhost:3333
- Remote debugging using localhost:3333
- 0x00000000 in ?? ()
- # Now the `monitor' command can be used.
- (gdb) monitor help
- # for output see [4]
- # Trying to upload the code gives this:
- (gdb) load
- Loading section .text, size 0x14595 lma 0x1000000
- Load failed
- # The OpenOCD output gives:
- Warn : memory write caused data abort (address: 0x01000000, size: 0x4, count: 0xf24)
- # It seems to be writing to Flash as if it were RAM. My guess is that
- # gdb also needs to be told where things are.
- # The gdbinitscript I have for the Segger JTAG / gdbserver just talks
- # to the monitor (gdbserver) giving it some non-standard commands to
- # enable flash writing.
- (gdb) monitor flash list
- {name at91sam7 base 1048576 size 262144 bus_width 4 chip_width 0}
- (gdb) monitor flash banks
- #0: at91sam7 at 0x00100000, size 0x00040000, buswidth 4, chipwidth 0
- # Ah, maybe it's protected memory?
- (gdb) monitor flash info 0
- #0 : at91sam7 at 0x00100000, size 0x00040000, buswidth 4, chipwidth 0
- # 0: 0x00000000 (0x4000 16kB) protected
- # 1: 0x00004000 (0x4000 16kB) protected
- # 2: 0x00008000 (0x4000 16kB) not protected
- # 3: 0x0000c000 (0x4000 16kB) not protected
- # 4: 0x00010000 (0x4000 16kB) not protected
- # 5: 0x00014000 (0x4000 16kB) not protected
- # 6: 0x00018000 (0x4000 16kB) not protected
- # 7: 0x0001c000 (0x4000 16kB) not protected
- # 8: 0x00020000 (0x4000 16kB) not protected
- # 9: 0x00024000 (0x4000 16kB) not protected
- # 10: 0x00028000 (0x4000 16kB) not protected
- # 11: 0x0002c000 (0x4000 16kB) not protected
- # 12: 0x00030000 (0x4000 16kB) not protected
- # 13: 0x00034000 (0x4000 16kB) not protected
- # 14: 0x00038000 (0x4000 16kB) not protected
- # 15: 0x0003c000 (0x4000 16kB) not protected
- at91sam7 driver information: Chip is AT91SAM7S256
- Cidr: 0x270b0941 | Arch: 0x0070 | Eproc: ARM7TDMI | Version: 0x001 | Flashsize: 0x00040000
- Master clock (estimated): 48054 KHz | External clock: 18432 KHz
- Pagesize: 256 bytes | Lockbits(16): 2 0x0003 | Pages in lock region: 128
- Securitybit: 0 | Nvmbits(2): 0 0x0
- # Switching off protection of the first two sectors:
- (gdb) mon flash protect 0 0 1 off
- cleared protection for sectors 0 through 1 on flash bank 0
- # Something fishy.. The "flash info 0" command says the flash is at
- # 0x00100000, while I'm trying to load it at 0x01000000?
- # Do the SAM7S256 and SAM7S512 use different memory maps? No.
- # Why is lma set to 0x01000000? The error message also says that's
- # the address with a write error.
- # OK, that was stupid. It was a linux/i386 elf. Fixing that:
- (gdb) load
- Loading section .rom_vectors, size 0x40 lma 0x100000
- Loading section .text, size 0x1805c lma 0x100040
- Loading section .rodata, size 0x2084 lma 0x11809c
- Loading section .got, size 0x23c lma 0x11a120
- Loading section .data, size 0xcec lma 0x11a35c
- Start address 0x100040, load size 110664
- Transfer rate: 5 KB/sec, 10060 bytes/write.
- (gdb)
- # Then stepping through the code works, and is quite fast too.
- # Breakpoints work up to 2. My original app code for SAM7X512 does
- # eventuall hang on the SAM7X256. It freezes somewhere in HAL config.
- # Let's see if upload speed can be set a bit higher. It doesn't seem
- # to be the JTAG speed (at 6MHz). Something else causes only 5Kb/sec
- # transfer rate. Seems I'm not the only one with the problem[5] on
- # this hardware.
- # Using fast memory access (slow is potentially safer?) it does seem
- # to work a bit faster: 5 -> 9 kB/sec.
- (gdb) monitor arm7_9 fast_memory_access enable
- [1] http://www.openhardware.net/Embedded_ARM/OpenOCD_JTAG/
- [2] http://www.olimex.com/dev/sam7-h256.html
- [3] http://www.olimex.com/dev/sam7-ex256.html
- [4] entry://20100915-174237
- [5] https://lists.berlios.de/pipermail/openocd-development/2010-July/015961.html
- Entry: monitor help
- Date: Wed Sep 15 17:42:37 CEST 2010
- add_help_text command_name helptext_string
- Add new command help text; Command can be multiple tokens. (command
- valid any time)
- add_usage_text command_name usage_string
- Add new command usage text; command can be multiple tokens. (command
- valid any time)
- arm
- ARM command group (command valid any time)
- arm core_state ['arm'|'thumb']
- display/change ARM core state
- arm disassemble address [count ['thumb']]
- disassemble instructions
- arm mcr cpnum op1 CRn op2 CRm value
- write coprocessor register
- arm mrc cpnum op1 CRn op2 CRm
- read coprocessor register
- arm reg
- display ARM core registers
- arm7_9
- arm7/9 specific commands (command valid any time)
- arm7_9 dbgrq ['enable'|'disable']
- use EmbeddedICE dbgrq instead of breakpoint for target halt
- requests (command valid any time)
- arm7_9 dcc_downloads ['enable'|'disable']
- use DCC downloads for larger memory writes (command valid any time)
- arm7_9 fast_memory_access ['enable'|'disable']
- use fast memory accesses instead of slower but potentially safer
- accesses (command valid any time)
- arm7_9 semihosting ['enable'|'disable']
- activate support for semihosting operations
- at91sam7
- at91sam7 flash command group (command valid any time)
- at91sam7 gpnvm bitnum ('set'|'clear')
- set or clear one General Purpose Non-Volatile Memory (gpnvm) bit
- bp [address length ['hw']]
- list or set hardware or software breakpoint
- command
- core command group (introspection) (command valid any time)
- command mode [command_name ...]
- Returns the command modes allowed by a command:'any', 'config', or
- 'exec'. If no command isspecified, returns the current command
- mode. Returns 'unknown' if an unknown command is given. Command
- can be multiple tokens. (command valid any time)
- command type command_name [...]
- Returns the type of built-in command:'native', 'simple', 'group',
- or 'unknown'. Command can be multiple tokens. (command valid any
- time)
- debug_level number
- Sets the verbosity level of debugging output. 0 shows errors only; 1
- adds warnings; 2 (default) adds other info; 3 adds debugging.
- (command valid any time)
- drscan tap_name [num_bits value]* ['-endstate' state_name]
- Execute Data Register (DR) scan for one TAP. Other TAPs must be in
- BYPASS mode.
- dump_image filename address size
- etm
- Emebdded Trace Macrocell command group (command valid any time)
- exit
- exit telnet session
- fast_load
- loads active fast load image to current target - mainly for profiling
- purposes
- fast_load_image filename address ['bin'|'ihex'|'elf'|'s19'] [min_address [max_length]]
- Load image into server memory for later use by fast_load; primarily
- for profiling (command valid any time)
- find <file>
- print full path to file according to OpenOCD search rules (command
- valid any time)
- flash
- NOR flash command group (command valid any time)
- flash banks
- Display table with information about flash banks. (command valid
- any time)
- flash erase_address ['pad'] address length
- Erase flash sectors starting at address and continuing for length
- bytes. If 'pad' is specified, data outside that range may also be
- erased: the start address may be decreased, and length increased,
- so that all of the first and last sectors are erased.
- flash erase_check bank_id
- Check erase state of all blocks in a flash bank.
- flash erase_sector bank_id first_sector_num last_sector_num
- Erase a range of sectors in a flash bank.
- flash fillb address value n
- Fill n bytes with 8-bit value, starting at word address. (No
- autoerase.)
- flash fillh address value n
- Fill n halfwords with 16-bit value, starting at word address. (No
- autoerase.)
- flash fillw address value n
- Fill n words with 32-bit value, starting at word address. (No
- autoerase.)
- flash info bank_id
- Print information about a flash bank.
- flash list
- Returns a list of details about the flash banks. (command valid any
- time)
- flash probe bank_id
- Identify a flash bank.
- flash protect bank_id first_sector [last_sector|'last'] ('on'|'off')
- Turn protection on or off for a range of sectors in a given flash
- bank.
- flash protect_check bank_id
- Check protection state of all blocks in a flash bank.
- flash write_bank bank_id filename offset
- Write binary data from file to flash bank, starting at specified
- byte offset from the beginning of the bank.
- flash write_image [erase] [unlock] filename [offset [file_type]]
- Write an image to flash. Optionally first unprotect and/or erase
- the region to be used. Allow optional offset from beginning of
- bank (defaults to zero)
- flush_count
- Returns the number of times the JTAG queue has been flushed.
- gdb_breakpoint_override ('hard'|'soft'|'disable')
- Display or specify type of breakpoint to be used by gdb 'break'
- commands. (command valid any time)
- gdb_port [port_num]
- Display or specify base port on which to listen for incoming GDB
- connections. No arguments reports GDB port; zero disables. (command
- valid any time)
- gdb_sync
- next stepi will return immediately allowing GDB to fetch register
- state without affecting target state (command valid any time)
- halt [milliseconds]
- request target to halt, then wait up to the specifiednumber of
- milliseconds (default 5) for it to complete
- help [command_name]
- Show full command help; command can be multiple tokens. (command
- valid any time)
- init
- Initializes configured targets and servers. Changes command mode
- from CONFIG to EXEC. Unless 'noinit' is called, this command is
- called automatically at the end of startup. (command valid any time)
- interface_list
- List all built-in interfaces (command valid any time)
- irscan [tap_name instruction]* ['-endstate' state_name]
- Execute Instruction Register (DR) scan. The specified opcodes are
- put into each TAP's IR, and other TAPs are put in BYPASS.
- jtag
- perform jtag tap actions (command valid any time)
- jtag arp_init
- Validates JTAG scan chain against the list of declared TAPs using
- just the four standard JTAG signals. (command valid any time)
- jtag arp_init-reset
- Uses TRST and SRST to try resetting everything on the JTAG scan
- chain, then performs 'jtag arp_init'. (command valid any time)
- jtag cget tap_name '-event' event_name
- Return any Tcl handler for the specified TAP event.
- jtag configure tap_name '-event' event_name handler
- Provide a Tcl handler for the specified TAP event.
- jtag drscan tap_name [num_bits value]* ['-endstate' state_name]
- Execute Data Register (DR) scan for one TAP. Other TAPs must be in
- BYPASS mode.
- jtag flush_count
- Returns the number of times the JTAG queue has been flushed.
- jtag init
- initialize jtag scan chain (command valid any time)
- jtag interface
- Returns the name of the currently selected interface. (command
- valid any time)
- jtag names
- Returns list of all JTAG tap names. (command valid any time)
- jtag pathmove start_state state1 [state2 [state3 ...]]
- Move JTAG state machine from current state (start_state) to state1,
- then state2, state3, etc.
- jtag tapdisable tap_name
- Try to disable the specified TAP using the 'tap-disable' TAP event.
- jtag tapenable tap_name
- Try to enable the specified TAP using the 'tap-enable' TAP event.
- jtag tapisenabled tap_name
- Returns a Tcl boolean (0/1) indicating whether the TAP is enabled
- (1) or not (0).
- jtag_khz [khz]
- With an argument, change to the specified maximum jtag speed. Pass 0
- to require adaptive clocking. With or without argument, display
- current setting. (command valid any time)
- jtag_nsrst_assert_width [milliseconds]
- delay after asserting srst in ms (command valid any time)
- jtag_nsrst_delay [milliseconds]
- delay after deasserting srst in ms (command valid any time)
- jtag_ntrst_assert_width [milliseconds]
- delay after asserting trst in ms (command valid any time)
- jtag_ntrst_delay [milliseconds]
- delay after deasserting trst in ms (command valid any time)
- jtag_rclk [fallback_speed_khz]
- With an argument, change to to use adaptive clocking if possible;
- else to use the fallback speed. With or without argument, display
- current setting. (command valid any time)
- jtag_reset trst_active srst_active
- Set reset line values. Value '1' is active, value '0' is inactive.
- load_image filename address ['bin'|'ihex'|'elf'|'s19'] [min_address] [max_length]
- log_output file_name
- redirect logging to a file (default: stderr) (command valid any time)
- mdb ['phys'] address [count]
- display memory bytes
- mdh ['phys'] address [count]
- display memory half-words
- mdw ['phys'] address [count]
- display memory words
- mflash
- mflash command group (command valid any time)
- mwb ['phys'] address value [count]
- write memory byte
- mwh ['phys'] address value [count]
- write memory half-word
- mww ['phys'] address value [count]
- write memory word
- nand
- NAND flash command group (command valid any time)
- nand drivers
- lists available NAND drivers (command valid any time)
- ocd_array2mem arrayname bitwidth address count
- convert a TCL array to memory locations and write the 8/16/32 bit
- values
- ocd_mem2array arrayname bitwidth address count
- read 8/16/32 bit memory and return as a TCL array for script
- processing
- pathmove start_state state1 [state2 [state3 ...]]
- Move JTAG state machine from current state (start_state) to state1,
- then state2, state3, etc.
- pld
- programmable logic device commands (command valid any time)
- poll ['on'|'off']
- poll target state; or reconfigure background polling
- power_restore
- Overridable procedure run when power restore is detected. Runs 'reset
- init' by default. (command valid any time)
- profile
- profiling samples the CPU PC
- rbp address
- remove breakpoint
- reg [(register_name|register_number) [value]]
- display or set a register; with no arguments, displays all registers
- and their values
- reset [run|halt|init]
- Reset all targets into the specified mode.Default reset mode is run,
- if not given.
- reset_config [none|trst_only|srst_only|trst_and_srst]
- [srst_pulls_trst|trst_pulls_srst|combined|separate]
- [srst_gates_jtag|srst_nogate] [trst_push_pull|trst_open_drain]
- [srst_push_pull|srst_open_drain]
- configure JTAG reset behavior (command valid any time)
- reset_nag ['enable'|'disable']
- Nag after each reset about options that could have been enabled to
- improve performance. (command valid any time)
- resume [address]
- resume target execution from current PC or address
- runtest num_cycles
- Move to Run-Test/Idle, and issue TCK for num_cycles.
- rwp address
- remove watchpoint
- sam7x256.cpu
- target command group (command valid any time)
- sam7x256.cpu arm
- ARM command group (command valid any time)
- sam7x256.cpu arm7_9
- arm7/9 specific commands (command valid any time)
- sam7x256.cpu arp_examine
- used internally for reset processing
- sam7x256.cpu arp_halt
- used internally for reset processing
- sam7x256.cpu arp_halt_gdb
- used internally for reset processing to halt GDB
- sam7x256.cpu arp_poll
- used internally for reset processing
- sam7x256.cpu arp_reset
- used internally for reset processing
- sam7x256.cpu arp_waitstate
- used internally for reset processing
- sam7x256.cpu array2mem arrayname bitwidth address count
- Writes Tcl array of 8/16/32 bit numbers to target memory
- sam7x256.cpu cget target_attribute
- returns the specified target attribute (command valid any time)
- sam7x256.cpu curstate
- displays the current state of this target
- sam7x256.cpu etm
- Emebdded Trace Macrocell command group (command valid any time)
- sam7x256.cpu eventlist
- displays a table of events defined for this target
- sam7x256.cpu invoke-event event_name
- invoke handler for specified event
- sam7x256.cpu mdb address [count]
- Display target memory as 8-bit bytes
- sam7x256.cpu mdh address [count]
- Display target memory as 16-bit half-words
- sam7x256.cpu mdw address [count]
- Display target memory as 32-bit words
- sam7x256.cpu mem2array arrayname bitwidth address count
- Loads Tcl array of 8/16/32 bit numbers from target memory
- sam7x256.cpu mwb address data [count]
- Write byte(s) to target memory
- sam7x256.cpu mwh address data [count]
- Write 16-bit half-word(s) to target memory
- sam7x256.cpu mww address data [count]
- Write 32-bit word(s) to target memory
- scan_chain
- print current scan chain configuration (command valid any time)
- script <file>
- filename of OpenOCD script (tcl) to run (command valid any time)
- shutdown
- shut the server down (command valid any time)
- sleep milliseconds ['busy']
- Sleep for specified number of milliseconds. "busy" will busy wait
- instead (avoid this). (command valid any time)
- soft_reset_halt
- halt the target and do a soft reset
- srst_deasserted
- Overridable procedure run when srst deassert is detected. Runs 'reset
- init' by default. (command valid any time)
- step [address]
- step one instruction from current PC or address
- svf filename ['quiet']
- Runs a SVF file.
- target_request
- target request command group (command valid any time)
- target_request debugmsgs ['enable'|'charmsg'|'disable']
- display and/or modify reception of debug messages from target
- targets [target]
- change current default target (one parameter) or prints table of all
- targets (no parameters) (command valid any time)
- telnet_port [port_num]
- Specify port on which to listen for incoming telnet connections. No
- arguments reports telnet port; zero disables. (command valid any
- time)
- test_image filename [offset [type]]
- tms_sequence ['short'|'long']
- Display or change what style TMS sequences to use for JTAG state
- transitions: short (default) or long. Only for working around JTAG
- bugs. (command valid any time)
- trace
- trace command group
- trace history ['clear'|size]
- display trace history, clear history or set size
- trace point ['clear'|address]
- display trace points, clear list of trace points, or add new
- tracepoint at address
- usage [command_name]
- Show basic command usage; command can be multiple tokens. (command
- valid any time)
- verify_image filename [offset [type]]
- verify_ircapture ['enable'|'disable']
- Display or assign flag controlling whether to verify values captured
- during Capture-IR. (command valid any time)
- verify_jtag ['enable'|'disable']
- Display or assign flag controlling whether to verify values captured
- during IR and DR scans. (command valid any time)
- version
- show program version (command valid any time)
- virt2phys virtual_address
- translate a virtual address into a physical address (command valid
- any time)
- wait_halt [milliseconds]
- wait up to the specified number of milliseconds (default 5) for a
- previously requested halt
- wp [address length [('r'|'w'|'a') value [mask]]]
- list (no params) or create watchpoints
- xsvf (tapname|'plain') filename ['virt2'] ['quiet']
- Runs a XSVF file. If 'virt2' is given, xruntest counts are
- interpreted as TCK cycles rather than as microseconds. Without the
- 'quiet' option, all comments, retries, and mismatches will be
- reported.
- Entry: Segger JLink OpenOCD
- Date: Thu Sep 16 09:59:14 CEST 2010
- Seems to be Supported [1].
- Actually, I need the Atmel SAM-ICE, which is restricted to Atmel
- devices[2][3]. The SAM-ICE is cheaper ($104 at DigiKey). The
- standard J-Link is 248 Euro.
- [1] https://lists.berlios.de/pipermail/openocd-development/2010-August/016312.html
- [2] http://www.segger.com/cms/j-link-oem-versions.html
- [3] http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3892
- Entry: Armpit scheme on Olimex SAM7-H256
- Date: Sun Sep 26 22:15:15 CEST 2010
- To build (see script in root dir)
- arm-eabi-as -mcpu=arm7tdmi armpit_00.0225.s -o a.o
- arm-eabi-ld -Map bin/armpit_00.0225_SAM7_H256.map --script armpit_build_link -o a.elf a.o
- To program: Use the following OpenOCD command. Note that the offset
- is necessary because the elf starts at 0. This is in contrast to the
- eCos elfs that start at the correct flash base address.
- flash write_image erase /opt/src/armpit/a.elf 0x100000 elf
- UPDATE: It flashes and seems to run fine, stepping in gdb. However I
- do have some config wrong because I don't see any console activity on
- DBGU and there is no virtual serial port popping up either..
- [1] http://www.olimex.com/dev/sam7-h256.html
- [2] http://armpit.sourceforge.net/
- Entry: Olimex stuff
- Date: Tue Sep 28 14:57:12 CEST 2010
- I got some eCos app loaded and running, but I can't set breakpoints.
- This worked before:
- Unable to set 32 bit software breakpoint at address 001001f8 - check that memory is read/writable
- This seems to work:
- (gdb) monitor gdb_breakpoint_override hard
- Entry: gdbserver
- Date: Wed Oct 13 11:34:58 CEST 2010
- I still don't have a proper way to reset the olimes ocd/at91
- combination such that "load, continue" will work.
- What seems to work is to:
- - quit gdb, quit OpenOCD
- - unplug everything (programmer + board)
- - start OpenOCD, start gdb, reset, load
- The following init sequence seems to work a bit:
- target remote :3333
- monitor poll
- monitor reset init
- monitor sleep 500
- ### needed for gdb 6.8 and higher
- set mem inaccessible-by-default off
- monitor flash probe 0
- monitor gdb_breakpoint_override hard
- monitor arm7_9 dcc_downloads enable
- # monitor arm7_9 fast_memory_access enable
- Some remarks:
- * The target needs to be halted before you can do anyting like
- uploading and setting breakpoints.
- * Why doesn't the program entry point change after `load'? On the
- Segger J-Link this seems to work just fine.
- * Reset seems to work, but it doesn't halt the target. Fix: use
- `soft_reset_halt'.
- // This is not initialized properly on Olimex board ??
- // const char bytes[] = {1,2,3,1,2,3,1,2,3,1,2,3};
- Entry: OpenOCD getting started
- Date: Thu Nov 11 13:16:05 EST 2010
- As I forget this every time:
- 1. start ocd, i.e. like in [1].
- 2. start gdb for arm and connect with the "target remote localhost 3333" connect.
- 3. initialize the arm chip, i.e. halt + init stack.
- steps 2. and 3. are best bundled in a script such as [2]
- cd ~/ecos/build/demo
- /opt/xc/arm9/bin/arm-linux-gnu-gdb -x ~/ecos/bin/eCos.gdb demo
- [1] http://zwizwa.be/darcs/pool/bin/ocd.SAM7-H256
- [2] http://zwizwa.be/darcs/ecos/bin/eCos.gdb
- Entry: More OpenOCD
- Date: Thu Nov 11 14:14:25 EST 2010
- A minefield. One thing is sure: target needs reset before `load', and
- I get different behaviour depending on the JTAG clock speed. Set to
- 300kHz or less, a "halt reset" will work, higher it doesn't always.
- Let's play a bit more.
- [1] http://www.mail-archive.com/[email protected]/msg13435.html
- Entry: OpenOCD current
- Date: Thu Nov 11 14:23:40 EST 2010
- git clone git://repo.or.cz/openocd.git
- cd openocd
- ./bootstrap
- Bootstrap complete. Quick start build instructions:
- 1. Build Jim Tcl
- git submodule init
- git submodule update
- cd jimtcl
- ./configure --with-jim-ext=nvp
- make
- make install
- 2. Configure
- ./configure --enable-maintainer-mode ....
- ./configure --enable-maintainer-mode --enable-ft2232_libftdi
- This one seems to work better.
- Playing it a bit more it seems to be "mon reset init" that doesn't
- work properly when JTAG clock is fast.
- Conclusion: it seems to work +- reliably when JTAG clock is set to a
- slow rate (i.e. 100-300 kHz) before "reset init" is invoked.
- Entry: LPC2119 ET-ARM STAMP
- Date: Sat Jul 11 15:30:55 CEST 2009
- The getting started document mentions the "LPC2000 flash utility"
- which can be downloaded[3] from Philips (NXP) website. There is a
- linux utilities here[4][6].
- Forum[5]. In order to get this to work convieniently, it's probably
- best to make a motherboard which is connected using a USBSERIAL 3.3V
- cable, and cut out the MAX3232 serial port. Have to wait for the
- Futurlec order.
- [1] http://www.ett.co.th
- [2] http://www.ett.co.th/prod2009/ET-ARM/ET_ARM_STAMP_ADUC7024.html
- [3] http://www.nxp.com/files/products/standard/microcontrollers/utilities/lpc2000_flash_utility.zip
- [4] http://www.pjrc.com/arm/lpc2k_pgm/
- [5] http://tech.groups.yahoo.com/group/lpc2000/
- [6] http://kroy.hu/lpc2k/
- Entry: Setting up AT91SAM7S-EK + Olimex ARM-USB-OCD
- Date: Wed Feb 2 12:22:38 EST 2011
- The Olimex ARM-USB-OCD has a RS232 port which can be plugged to the
- Atmel AT91SAM7S-EK (AT9). It is an FTDI2232C:
- Feb 2 12:26:50 zoo kernel: [4894878.109218] usb 1-4.4.4: new full speed USB device using ehci_hcd and address 35
- Feb 2 12:26:50 zoo kernel: [4894878.226327] usb 1-4.4.4: New USB device found, idVendor=15ba, idProduct=0003
- Feb 2 12:26:50 zoo kernel: [4894878.226330] usb 1-4.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
- Feb 2 12:26:50 zoo kernel: [4894878.226393] usb 1-4.4.4: Product: Olimex OpenOCD JTAG
- Feb 2 12:26:50 zoo kernel: [4894878.226395] usb 1-4.4.4: Manufacturer: Olimex
- Feb 2 12:26:50 zoo kernel: [4894878.229669] usb 1-4.4.4: Ignoring serial port reserved for JTAG
- Feb 2 12:26:50 zoo kernel: [4894878.232305] ftdi_sio 1-4.4.4:1.1: FTDI USB Serial Device converter detected
- Feb 2 12:26:50 zoo kernel: [4894878.232333] usb 1-4.4.4: Detected FT2232C
- Feb 2 12:26:50 zoo kernel: [4894878.232348] usb 1-4.4.4: Number of endpoints 2
- Feb 2 12:26:50 zoo kernel: [4894878.232350] usb 1-4.4.4: Endpoint 1 MaxPacketSize 64
- Feb 2 12:26:50 zoo kernel: [4894878.232352] usb 1-4.4.4: Endpoint 2 MaxPacketSize 64
- Feb 2 12:26:50 zoo kernel: [4894878.232355] usb 1-4.4.4: Setting MaxPacketSize 64
- Feb 2 12:26:50 zoo kernel: [4894878.233289] usb 1-4.4.4: FTDI USB Serial Device converter now attached to ttyUSB2
- To identify usb serial ports I have a small script[1][2] that resides
- in /lib/udev and tries to provide a unique name for the device. The
- OCD doesn't seem to expose a serial number, so i'm generating a tty
- name based on the idVendor idProduct info, which then becomes
- /dev/tty-15ba0003 which I've linked to /dev/ttyOCD.
- Out of the box, the AT91 doesn't seem to produce any serial output, at
- least not at 9600 baud.
- Starting the OpenOCD script[3] I used for the other SAM7 board seems
- to work:
- [email protected]:~/bin$ ./ocd.SAM7-H256
- #!/bin/bash
- cat $0
- SCRIPTS=/usr/local/share/openocd/scripts
- exec openocd \
- --file $SCRIPTS/interface/arm-usb-ocd.cfg \
- --file $SCRIPTS/target/sam7x256.cfg \
- --file $0.cfg \
- Open On-Chip Debugger 0.5.0-dev-00586-gc62fb3f (2010-11-11-14:30)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.berlios.de/doc/doxygen/bugs.html
- Info : only one transport option; autoselect 'jtag'
- srst_only srst_pulls_trst srst_gates_jtag srst_open_drain
- 300 kHz
- dcc downloads are enabled
- fast memory access is enabled
- force hard breakpoints
- Info : clock speed 300 kHz
- Info : JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
- Info : Embedded ICE version 1
- Info : sam7x256.cpu: hardware has 2 breakpoint/watchpoint units
- Info : JTAG tap: sam7x256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
- Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in Thumb state due to debug-request, current mode: Supervisor
- cpsr: 0x40000033 pc: 0x000007f4
- I spent some time in november getting the other ARM board setup after
- my move. That took some time: I had to work around an issue by
- setting the clock slower before reset, then setting faster before
- load. See [3][4].
- Next: get something running on the arm board.
- So I got something to run + output to the serial port (DBGU 9600
- baud). However, only 2 or 3 times this worked, after that I no longer
- get any signal on the debug port. Also measured on the analog scope.
- I'm able to single-step code on the ARM, but breakpoints (actually I
- tried the "next" command) don't work reliably.
- My guess is there's a bug with the OpenOCD somewhere. Let's see if
- there are any config issues I should be aware of.
- I've upgraded OpenOCD to git tag
- 75cdbff5aa93d93e414cb22d413f41fb38a076bb. After power cylcing the
- board and the OCD it seems to work again.
- When using just `load' and `continue' everything seems to work just
- fine. Using `reset' (see eCos.gdb) messes things up for good.
- [1] http://zwizwa.be/darcs/pool/bin/ttyUSB_id
- [2] entry://../pool/20101231-230904
- [3] entry://20101111-142340
- [4] http://zwizwa.be/darcs/ecos/bin/eCos.gdb
- Entry: AT91SAM7 devices
- Date: Mon Feb 7 14:08:57 EST 2011
- SAM7S : 64 pins http://www.atmel.com/dyn/products/devices.asp?category_id=163&family_id=605&subfamily_id=1586&source=left_nav
- SAM7X : 100 pins http://www.atmel.com/dyn/products/devices.asp?category_id=163&family_id=605&subfamily_id=1724&source=left_nav
- Flash RAM
- -------------------------
- SAM7S256 256K 64K
- SAM7S512 512K 64K
- SAM7X256 256K 64K
- SAM7X512 512K 128K
- Entry: AT91SAM7-EK expansion header
- Date: Tue Feb 8 09:12:16 EST 2011
- To what does the numbering on the expansion header correspond? There
- are numbers 0-31 and AD4-AD7. Looking at the data sheet these are
- probably the PA PIO numbers not package pin numbers.
- That seems to be corrected. AD4-AD7 are dedicated pins while AD0-AD3
- are mapped to PA17-PA20.
- For SPI there is:
- perA perB
- ------------------
- PA11 NPCS0 PWM0
- PA12 MISO PWM1
- PA13 MOSI PWM2
- PA14 SPCK PWM3
- Entry: OpenOCD slow?
- Date: Sat Feb 12 12:12:08 EST 2011
- I get 8kb/sec transfer when I upload the image. The reason is
- probably the Flash write speed, as other JTAG tranfers go very fast.
- Entry: More robust OCD : USB replug
- Date: Sun Feb 13 13:14:56 EST 2011
- Error: ftdi_write_data: usb bulk write failed
- Error: couldn't write MPSSE commands to FT2232
- Polling target failed, GDB will be halted. Polling again in 6300ms
- Can we work around that?
- Also for serial connectors, I see that minicom can detect an unplugged
- cable and will reconnect properly.
- Entry: OpenOCD problems target replug
- Date: Tue Feb 15 09:07:12 EST 2011
- When disconnecting the target I get this:
- Error: Target not halted
- Error: auto_probe failed
- Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
- Error: attempted 'gdb' connection rejected
- Restarting OOCD helps.
- Entry: OpenOCD hardware breakpoing issues
- Date: Tue Feb 15 12:26:21 EST 2011
- Another issue: sometimes gdb seems to loose the pedals when it won't
- issue `thbreak' or `next' correctly. Maybe the hardware breakpoint
- management gets messed up?
- Error: could not add breakpoint
- Is there a way to list the hardware breakpoints? Yes:
- mon bp
- That doesn't seem to list anything though. I get the following error
- message:
- Error: address + size wrapped(0xfffffffe, 0x00000004)
- To list the gdb-known breakpoints:
- (gdb) info breakpoints
- Num Type Disp Enb Address What
- 7 hw breakpoint del y 0x00101498 in demo at /home/tom/ubidata-tom/src/spi/spi.c:339
- Something's not right. Exiting OCD does solve the problem.
- It seems that the "reset" command doesn't really perform a full reset.
- Is there a way to reset everything, just as it would be done at init?
- My current workaround is to use a "while sleep 1; do ... ; done" loop
- around oocd, and invoke "mon shutdown" from gdb, followed by a
- reconnect.
- Entry: ocd over network problem
- Date: Wed Mar 23 13:14:54 EDT 2011
- On localhost works fine:
- requesting target halt and executing a soft reset
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x600000d3 pc: 0x00000000
- - Loading /home/tom/priv/git-private/ubidata/dbb_trailer/build/out/arm_tom/test-blockmanager
- Loading section .rom_vectors, size 0x40 lma 0x100000
- Loading section .text, size 0x2cc34 lma 0x100040
- Loading section .rodata, size 0x198c lma 0x12cc74
- Loading section .data, size 0x7b4 lma 0x12e600
- Start address 0x100040, load size 191924
- Transfer rate: 10 KB/sec, 12794 bytes/write.
- - Done.
- - Continuing.
- Same from other host, either using tunneling or direct TCP connection
- the speed is something like 195 KB/sec and it doesn't seem to upload
- properly.
- ?
- Entry: openocd OLIMEX OCD-USB-EW
- Date: Mon May 16 14:36:32 CEST 2011
- --enable-arm-jtag-ew
- Entry: OpenOCD on the AT91
- Date: Sat May 28 12:14:09 CEST 2011
- It's slow and I don't know why. Setting debug loglevel gives this as
- the main programming loop:
- Debug: 15414 145857 target.c:1652 target_write_u32(): address: 0xffffff64, value: 0x5a03d801
- Debug: 15415 145857 embeddedice.c:502 embeddedice_write_reg(): 0: 0x00000004
- Debug: 15416 145857 embeddedice.c:502 embeddedice_write_reg(): 0: 0x00000005
- Debug: 15417 145873 at91sam7.c:353 at91sam7_flash_command(): Flash command: 0x5a03d801, flash bank: 1, page number: 984
- Debug: 15418 145874 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0xffffff68, size: 0x00000004, count: 0x00000001
- Debug: 15420 145889 target.c:1575 target_read_u32(): address: 0xffffff68, value: 0x00000401
- Debug: 15421 145889 at91sam7.c:328 at91sam7_wait_status_busy(): status[0]: 0x401
- Debug: 15422 145889 at91sam7.c:1102 at91sam7_write(): Write flash bank:0 page number:984
- Debug: 15423 145889 embeddedice.c:502 embeddedice_write_reg(): 0: 0x00000004
- Debug: 15424 145889 embeddedice.c:502 embeddedice_write_reg(): 0: 0x00000005
- So what we see here is that the flash command 0x5a03d801 goes to
- register 0xffffff64. Looking at the data sheet this is a block of 256
- registers called MC (memory controller) at 0xffffff00, which is
- documented in section 18 in the AT91SAM7X datasheet. At offset 60 and
- 70 in this window are two EFCs : embedded Flash Controllers which are
- documented in section 19.
- 0x64 : MC_FCR : Memory Controller Flash Command Register
- 5A 0 3D8 0 1
- key page command
- = WP (write page)
- The key is the write-protection key, always 0x5A
- 0x68 : MC_FSR : Memory Controller Flash Status Register
- bit 0 is the ready bit.
- -> find out if this causes the delay
- No it doesn't : that bit is 1 when it's read.
- Ok, I tried again on the host and I get 7kByte/sec, but it doesn't
- work properly.
- Why is this so buggy? I had similar problems a couple of months ago.
- Is it just that I miss some console messages, or is it electrical?
- I think it's worth investing some time to see how this actually works,
- so I can understand the error messages.
- Entry: gdb cheat sheet
- Date: Sat May 28 16:34:23 CEST 2011
- # List breakpoints
- info breakpoints
- # List breakpoints in monitor. This doesn't always show the
- # breakpoints; it seems GDB will set them at a `continue' command. To
- # verify, log into OpenOCD using telnet and execute the `bp' command
- # when gdb is inside a `continue' command.
- mon bp
- # List memory map
- info mem
- Entry: force hard breakpoints
- Date: Sat May 28 16:43:42 CEST 2011
- dcc downloads are enabled
- fast memory access is enabled
- force hard breakpoints
- Entry: OpenOCD, scripting in tcl
- Date: Sun May 29 13:57:05 CEST 2011
- The thing is: OpenOCD is not only useful for gdb, but another
- debugger/monitor could be bolted on. It might be a good idea to get
- to know it a bit better.
- Cheat sheet
- # Load 10 bytes (8) from memory at 0xF000 ainto var (arr) and print it
- # to the console.
- mem2array arr 8 0xF000 10
- puts $arr
- # The bytes arrive on the OpenOCD console. How to make them go to the
- # GDB console?
- # startup.tcl
- [email protected]:~/git/openocd$ find -name startup.tcl
- ./src/jtag/startup.tcl
- ./src/startup.tcl
- ./src/target/startup.tcl
- ./src/helper/startup.tcl
- ./src/server/startup.tcl
- ./src/flash/startup.tcl
- [1] http://openocd.berlios.de/doc/html/About-Jim_002dTcl.html
- [2] http://openocd.berlios.de/doc/html/Tcl-Crash-Course.html#Tcl-Crash-Course
- Entry: OpenOCD docs
- Date: Sun May 29 15:00:14 CEST 2011
- It would be helpful to read the OpenOCD documentation once,
- completely.
- ./configure --enable-maintainer-mode --enable-ft2232_libftdi --enable-doxygen-pdf
- make -C doc pdf
- make doxygen
- (!!! apt-get install doxygen)
- doc/openocd.pdf
- doxygen/latex/refman.pdf (1500 pages!)
- Entry: Python scripting in GDB
- Date: Sun May 29 15:21:06 CEST 2011
- [1] http://sourceware.org/gdb/wiki/PythonGdb
- [2] http://sourceware.org/gdb/wiki/PythonGdbTutorial
- Entry: OpenOCD bugs
- Date: Sun May 29 16:09:57 CEST 2011
- I'm trying to get to a reliable workaround for all the bugs I run
- into. Up to now there hasn't been a simple pattern. This is an
- attempt to separate multiple bugs + their workaround.
- * Error: address + size wrapped(0xffffffff, 0x00000004)
- This is supposed to be a bug in GDB[1]. I have no reliable
- workaround.
- * Target not halted, starts running when left alone for a while
- (i.e. +- 1 hour)
- Could be WDT?
- It seems to be seriously messed up. I can't fix it with just software.
- Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- Error: Jazelle debug entry -- BROKEN!
- Error: Jazelle state handling is BROKEN!
- target state: halted
- target halted in Jazelle state due to debug-request, current mode: Supervisor
- cpsr: 0x61000013 pc: 0x00106a72
- requesting target halt and executing a soft reset
- Error: Jazelle state handling is BROKEN!
- target state: halted
- target halted in Jazelle state due to debug-request, current mode: Supervisor
- cpsr: 0x610000d3 pc: 0x00000000
- 1000 kHz
- There are 3 things to reset:
- - target power
- - programmer power
- - OpenOCD
- Assuming it's not the programmer, it should be possible for OpenOCD to
- reset the chip, whatever the state it is in. So assume the bug is
- with OpenOCD and restart it.
- When I reset just OpenOCD (not the board) I run into the other error:
- GDB: Cannot find bounds of current function
- OpenOCD: Error: address + size wrapped(0xffffffff, 0x00000004)
- Doing "reset" and "continue" a couple of times will eventually pull it
- back in line.
- Summary: I managed to reset it:
- - by re-starting OpenOCD
- - by fiddling a bit with GDB
- - did not touch target nor programmer power
- That should be automatable.
- [1] http://lists.berlios.de/pipermail/openocd-development/2009-February/004684.html
- Entry: OpenOCD all zeros
- Date: Sun May 29 17:01:01 CEST 2011
- The following problem was solved by power-cyling the (DBB) board:
- Open On-Chip Debugger 0.5.0-dev-00886-g6152c29 (2011-05-29-14:08)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.berlios.de/doc/doxygen/bugs.html
- Info : only one transport option; autoselect 'jtag'
- srst_only srst_pulls_trst srst_gates_jtag srst_open_drain
- Warn : use 'at91sam7s256.cpu' as target identifier, not '0'
- debug_level: 2
- 1 kHz
- dcc downloads are enabled
- fast memory access is enabled
- force hard breakpoints
- adapter_nsrst_delay: 200
- jtag_ntrst_delay: 200
- Info : clock speed 1 kHz
- Error: JTAG scan chain interrogation failed: all zeroes
- Error: Check JTAG interface, timings, target power, etc.
- Error: Trying to use configured scan chain anyway...
- Error: at91sam7s256.cpu: IR capture error; saw 0x00 not 0x01
- Warn : Bypassing JTAG setup events due to errors
- Info : Embedded ICE version 0
- Error: unknown EmbeddedICE version (comms ctrl: 0x00000000)
- Info : at91sam7s256.cpu: hardware has 2 breakpoint/watchpoint units
- debug_level: 1
- Error: JTAG scan chain interrogation failed: all zeroes
- Error: Check JTAG interface, timings, target power, etc.
- Error: Trying to use configured scan chain anyway...
- Error: at91sam7s256.cpu: IR capture error; saw 0x00 not 0x01
- Warn : Bypassing JTAG setup events due to errors
- Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- Error: timed out while waiting for target halted
- TARGET: at91sam7s256.cpu - Not halted
- Runtime Error: ./ocd.SAM7-H256.cfg:38:
- in procedure 'script'
- at file "embedded:startup.tcl", line 58
- in procedure 'reset' called at file "./ocd.SAM7-H256.cfg", line 38
- Entry: OpenOCD errors summary
- Date: Sun May 29 17:03:55 CEST 2011
- TODO: verify the following errors and workarounds.
- - Error: JTAG scan chain interrogation failed: all zeroes
- This is solved by a board power-cycle and OpenOCD restart.
- - Error: Jazelle debug entry -- BROKEN!
- Restarting OpenOCD then brings it to a state where the following
- occurs:
- - Error: address + size wrapped(0xffffffff, 0x00000004)
- This seems to be a generic error caused by GDB getting confused by
- what it gets from OpenOCD, or some other GDB-related issue.
- This is fixable by "nudging", i.e. "reset" + "continue" on the GDB
- prompt: finally it does seem to run reliably, stepping + breakpoints.
- Entry: OpenOCD console output to GDB
- Date: Sun May 29 17:52:15 CEST 2011
- Console output to GDB goes through:
- src/server/gdb_server.c :
- static int gdb_output_con(struct connection *connection, const char* line);
- This seems to be only used in:
- static void gdb_log_callback(void *priv, const char *file, unsigned line,
- const char *function, const char *string)
- What I think is going on here is that log_add_callback() adds to some
- kind of global logging facility. Next is to find out how to "puts" to
- that.
- To find a list of commands, do:
- grep -re ".name = " src/
- It seems that "list" is what I'm looking for.
- Probably a better candidate is "echo", defined in src/command.c :
- .name = "echo",
- .handler = jim_echo,
- .mode = COMMAND_ANY,
- .help = "Logs a message at \"user\" priority. "
- "Output message to stdout. "
- "Option \"-n\" suppresses trailing newline",
- .usage = "[-n] string",
- This calls LOG_USER / LOG_USER_N.
- Entry: AT91SAM7 back channel
- Date: Sun May 29 19:39:03 CEST 2011
- Are the DBGU ports/registers accessible through JTAG in monitor mode?
- Data sheet SAM7S 12.6.1
- * Find out what monitor mode does (as opposed to HALT mode) [1]
- * What are COMMTX and COMMRX signals.
- I'm browsing [1] looking for monitor mode at 5.9 and I find debug
- communication channel (DCC) at 5.8. Maybe that's what I'm looking
- for.
- Googling for '"coprocessor 14" openocd' I get [2]. On the ARM side
- it's just a MCR / MRC instruction. On the host side it's scan chain
- 2.
- Is this the same DCC as in "dcc downloads" ? Indeed. This mechanism
- is already used; I've found some ARM code so it looks like it places
- some code in RAM to handle the other side. Cool.
- It has some setup code in arm7_9_common.c and the bulk in
- embeddedice.c (embeddedice_write_dcc)
- So this _should_ definitely be workable. How to go about it then?
- [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/I901036.html
- [2] http://openocd.berlios.de/doc/html/Architecture-and-Core-Commands.html
- Entry: Getting debug info from GDB into OpenOCD
- Date: Mon May 30 10:13:22 CEST 2011
- I have a memory buffer that I would like to inspect with some kind of
- script. I have the option to use the (distorted) gdb scripting
- language, or to use jim tcl on the OpenOCD side.
- For the latter, I wonder how to translate symbols from GDB and pass
- them to the "monitor" command. The default behaviour is just to pass
- anything after the monitor command verbatim, not dereferencing
- variables.
- It's probably best to just write the scripts in GDB.
- Entry: OpenOCD still unreliable
- Date: Mon May 30 18:40:17 CEST 2011
- I'm getting closer to +- reliable operation. However, once in a
- couple I get this:
- stepi ignored. GDB will now fetch the register state from the target.
- A couple of stepi commands (3) right after "reset init" seem to solve
- this problem.
- Entry: More OpenOCD errors
- Date: Mon May 30 19:40:20 CEST 2011
- Error: Target not halted
- Error: auto_probe failed
- Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
- Error: attempted 'gdb' connection rejected
- It doesn't recover from that. This (I assume) is because of the
- board/firmware bug that causes sporadic resets.
- Fix OpenOCD so it restarts whenever this happens. Let's try to
- restart manually:
- Error: JTAG scan chain interrogation failed: all zeroes
- Error: Check JTAG interface, timings, target power, etc.
- Error: Trying to use configured scan chain anyway...
- Error: at91sam7s256.cpu: IR capture error; saw 0x00 not 0x01
- Warn : Bypassing JTAG setup events due to errors
- Info : Embedded ICE version 0
- Error: unknown EmbeddedICE version (comms ctrl: 0x00000000)
- Info : at91sam7s256.cpu: hardware has 2 breakpoint/watchpoint units
- Reason: board power failure.
- Entry: OpenOCD ARM DCC debug channel
- Date: Fri Jun 3 17:09:35 CEST 2011
- [1] http://openocd.berlios.de/doc/html/Architecture-and-Core-Commands.html
- Entry: OpenOCD again
- Date: Tue Jun 7 23:47:34 CEST 2011
- Now using the SAM7S Atmel EK, I get a problem at startup. This is
- right after halt. The mmw is the first write that resets the device.
- Also if I leave it at 3000 khz, gdb doesn't want to connect.
- [email protected]:~/ecos-build/bin$ ./ocd.SAM7
- Open On-Chip Debugger 0.5.0-dev-00886-g6152c29 (2011-05-29-14:26)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.berlios.de/doc/doxygen/bugs.html
- Info : only one transport option; autoselect 'jtag'
- srst_only srst_pulls_trst srst_gates_jtag srst_open_drain
- Warn : use 'at91sam7s256.cpu' as target identifier, not '0'
- debug_level: 2
- 100 kHz
- dcc downloads are enabled
- fast memory access is enabled
- force hard breakpoints
- adapter_nsrst_delay: 200
- jtag_ntrst_delay: 200
- Info : clock speed 100 kHz
- Info : JTAG tap: at91sam7s256.cpu tap/device found: 0x3f0f0f0f (mfg: 0x787, part: 0xf0f0, ver: 0x3)
- Info : Embedded ICE version 1
- Info : at91sam7s256.cpu: hardware has 2 breakpoint/watchpoint units
- debug_level: 1
- 100 kHz
- Warn : srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Abort
- cpsr: 0x200000d7 pc: 0x000006e8
- requesting target halt and executing a soft reset
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x200000d3 pc: 0x00000000
- Warn : memory write caused data abort (address: 0xfffffd00, size: 0x4, count: 0x1)
- in procedure 'mww'
- 3000 kHz
- receiving debug messages from current target charmsg
- Checking:
- /usr/local/share/openocd/scripts/target/at91sam7sx.cfg
- target create $_TARGETNAME arm7tdmi -endian $_ENDIAN -chain-position $_TARGETNAME -variant arm7tdmi
- $_TARGETNAME configure -event reset-init {
- soft_reset_halt
- # RSTC_CR : Reset peripherals
- mww 0xfffffd00 0xa5000004
- # disable watchdog
- mww 0xfffffd44 0x00008000
- # enable user reset
- mww 0xfffffd08 0xa5000001
- # CKGR_MOR : enable the main oscillator
- mww 0xfffffc20 0x00000601
- sleep 10
- # CKGR_PLLR: 96.1097 MHz
- mww 0xfffffc2c 0x00481c0e
- sleep 10
- # PMC_MCKR : MCK = PLL / 2 ~= 48 MHz
- mww 0xfffffc30 0x00000007
- sleep 10
- # MC_FMR: flash mode (FWS=1,FMCN=73)
- mww 0xffffff60 0x00490100
- sleep 100
- }
- Pfff.. If I remove the "reset init" in the startup script, it seems
- to come up just fine. Maybe that never really worked properly? I
- don't remember.
- One thing is clear: it doesn't like 3000 kHz. I thought it went
- faster.. If I switch to 1000 khz, it seems to work.
- So, again a buch of problems that are too confusing for me to see what
- is actually going on. I got it working on the Ubi board but the EK is
- borked again.
- Now I do an upload at 3000 kHz and that works:
- (gdb) mon jtag_khz 3000
- 3000 kHz
- (gdb) load
- Loading section .rom_vectors, size 0x40 lma 0x100000
- Loading section .text, size 0x28db8 lma 0x100040
- Loading section .rodata, size 0x7930 lma 0x128df8
- Loading section .data, size 0x1044 lma 0x130728
- Start address 0x100040, load size 202604
- Transfer rate: 8 KB/sec, 13506 bytes/write.
- Let's try 6000: seems to work too.
- This is weird... Do flash uploads actually talk to the processor or
- directly to the flash?
- Maybe it's time to start paying attention to the CPSR.
- I see several different states:
- 0x600000d3 (normal)
- 0x200000d3
- 0x200000d7
- 0x400000d3
- Let's summarize:
- - uploads do work at 6000 kHz if the state is ok
- - "reset init" is not reliable: mww error immediately after soft_reset_halt
- Crap.. can't add comments after a line in jim tcl!
- Ha.. removing the soft_reset_halt in the init routine make the data
- abort error go away.
- Entry: OpenOCD reset-init event
- Date: Wed Jun 8 01:31:26 CEST 2011
- So, it looks like the trouble from last post is mostly that
- "soft_reset_halt" is called inside the reset-init event handler in the
- at91sam7sx.cfg file. Removing it makes it behave better.
- Comparing it with the at91sam7x256.cfg file there is also no
- "soft_reset_halt".
- [1] http://openocd.berlios.de/doc/html/Config-File-Guidelines.html
- Entry: AT91SAM7 setup from scratch
- Date: Sun Jun 12 18:05:17 CEST 2011
- I've been using eCos up to now. How to work on the bare metal? This
- is the program I'm trying to run, residing in the file sam7.S
- main: nop
- nop
- nop
- b main
- Here's the contents of the makefile:
- all: sam7.elf
- clean:
- rm -rf *~ *.o *.elf
- CC = arm-eabi-gcc -mcpu=arm7tdmi -O0 -g
- LD = arm-eabi-gcc -mno-thumb-interwork -mcpu=arm7tdmi -Wl,-static -g -nostdlib
- OBJDUMP = arm-eabi-objdump
- %.o: %.S
- $(CC) -o [email protected] -c $<
- %.elf: %.o %.ld
- $(LD) -T$*.ld -o [email protected] $*.o
- %.dump: %.elf
- $(OBJDUMP) -h $<
- I'm using the following linker script which places everything in RAM.
- SECTIONS
- {
- . = 0x200000;
- .text : { *(.text) }
- .data : { *(.data) }
- .bss : { *(.bss) }
- }
- Compiling this to arm7.elf and loading with gdb enables me to step
- through the code if I use:
- set $pc = 0x200000
- Next is to set the reset vector and maybe put it in flash? Though RAM
- seems a lot more convenient if it fits..
- Let's peek in the eCos code to see what vectors.o looks like:
- 0 .text 00000564
- 1 .data 000001d8
- 2 .bss 00001310
- 3 .vectors 00000040
- 4 .fixed_vectors 00000140
- It will place the .vectors at the start of rom. So where is that
- section defined?
- packages/hal/arm/arch/current/src/vectors.S
- It seems that this space contains instructions either as branch or
- direct pc load, but not addresses.
- #ifdef CYGSEM_HAL_ROM_RESET_USES_JUMP
- // Assumption: ROM code has these vectors at the hardware reset address.
- // A simple jump removes any address-space dependencies [i.e. safer]
- b reset_vector // 0x00
- #else
- ldr pc,.reset_vector // 0x00
- #endif
- Always difficult to see what is an ARM-ism, and what is an AT91-ism.
- Looks like for arm the vectors are always code. I'm not sure if they
- are always at 0 though.. I seem to have found some info online about
- an LPC that starts somewhere else, in Flash. Some more info [1][2].
- For linker docs see [3].
- [1] http://sourceware.org/ml/ecos-discuss/1999-10/msg00087.html
- [2] http://sourceware.org/ml/ecos-discuss/1999-10/msg00095.html
- [3] http://www.delorie.com/gnu/docs/binutils/ld_9.html
- Entry: ARM instruction set
- Date: Sun Jun 12 19:47:26 CEST 2011
- Rules of thumb (har har):
- - Destination register is leftmost, operands rightmost.
- - Immediates need pound sign #
- - The 0xFFFFFFFF word is an invalid instruction
- [1] http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf
- Entry: arm asm/dasm
- Date: Thu Jun 16 18:27:05 CEST 2011
- For Staapl it might be intersting to try to figure out how to convert
- between binary and assembler using objdump.
- This works:
- arm-eabi-objdump -b binary -m arm -D foo
- Here -D is used instead of -d, because apparently the raw binary data
- is interpreted to be in .data segement.
- Maybe it's simpler to convert bin to .o with all data in the .text
- segment:
- arm-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.text foo foo.o
- But that doesn't set the CODE attribute that are in ordinary binaries,
- but the DATA attribute is set. Note that renaming happens after
- setting flags.
- arm-eabi-objcopy -I binary -O elf32-littlearm -B arm --rename-section .data=.text --set-section-flags .data=code foo foo.o
- To make it less confusing it seems better to reorder the flags, though
- that doesn't change functionality
- arm-eabi-objcopy \
- -I binary -O elf32-littlearm -B arm \
- --set-section-flags .data=code \
- --rename-section .data=.text foo foo.o
- Entry: $pc not reset after soft_reset_halt
- Date: Wed Jun 22 02:29:57 CEST 2011
- Is this because of GDB? I.e GDB's cache of the register values gets
- out of sync with the machine? Note that "mon reg" does seem to give
- the correct values.
- (gdb) mon soft_reset_halt
- requesting target halt and executing a soft reset
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x200000d3 pc: 0x00000000
- (gdb) info registers
- r0 0x0 0
- r1 0x6f 111
- r2 0x204714 2115348
- r3 0x10000002 268435458
- r4 0x2006a8 2098856
- r5 0x13 19
- r6 0x20388c 2111628
- r7 0x1d 29
- r8 0x20384c 2111564
- r9 0x200750 2099024
- r10 0x2006e0 2098912
- r11 0x20384c 2111564
- r12 0x2008d8 2099416
- sp 0x203800 0x203800
- lr 0x1143a4 1131428
- pc 0x11e4a8 0x11e4a8
- fps 0x0 0
- cpsr 0x20000013 536870931
- It happened again on a stepi. Indeed it seems to be just that gdb's
- idea of the registers gets messed up, so it will set them according to
- a previously saved state before stepping.
- The following is the OpenOCD debug output when stepping after a
- soft_reset_halt. The PC is supposed to be at 0, but somehow it gets
- set at 0x001100f0 which was the state before soft_reset_halt.
- The problem does not go away with restarting gdb. Restarting OpenOCD
- however does fix it.
- Debug: 56656 3980801 gdb_server.c:2201 gdb_input_inner(): received packet: 's'
- Debug: 56657 3980801 target.c:1062 target_call_event_callbacks(): target event 7 (gdb-start)
- Debug: 56658 3980801 gdb_server.c:1455 gdb_step_continue_packet(): -
- Debug: 56659 3980801 gdb_server.c:1475 gdb_step_continue_packet(): step
- Debug: 56660 3980801 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0x00000000, size: 0x00000004, count: 0x00000001
- Debug: 56661 3980811 target.c:1605 target_read_u32(): address: 0x00000000, value: 0xe59ff018
- Debug: 56662 3980811 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0x00000020, size: 0x00000004, count: 0x00000001
- Debug: 56663 3980822 target.c:1605 target_read_u32(): address: 0x00000020, value: 0x001100f0
- Debug: 56664 3980822 arm7_9_common.c:1615 arm7_9_restore_context(): -
- Debug: 56665 3980822 arm7_9_common.c:1638 arm7_9_restore_context(): examining Supervisor mode
- Debug: 56666 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r0
- Debug: 56667 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r1
- Debug: 56668 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r2
- Debug: 56669 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r3
- Debug: 56670 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r4
- Debug: 56671 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r5
- Debug: 56672 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r6
- Debug: 56673 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r7
- Debug: 56674 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r8
- Debug: 56675 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r9
- Debug: 56676 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r10
- Debug: 56677 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r11
- Debug: 56678 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: r12
- Debug: 56679 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: pc
- Debug: 56680 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: cpsr
- Debug: 56681 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 0 mode Supervisor with value 0xffffffff
- Debug: 56682 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 1 mode Supervisor with value 0xffffffff
- Debug: 56683 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 2 mode Supervisor with value 0xffffffff
- Debug: 56684 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 3 mode Supervisor with value 0xffffffff
- Debug: 56685 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 4 mode Supervisor with value 0xffffffff
- Debug: 56686 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 5 mode Supervisor with value 0xffffffff
- Debug: 56687 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 6 mode Supervisor with value 0xffffffff
- Debug: 56688 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 7 mode Supervisor with value 0xffffffff
- Debug: 56689 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 8 mode Supervisor with value 0xffffffff
- Debug: 56690 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 9 mode Supervisor with value 0xffffffff
- Debug: 56691 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 10 mode Supervisor with value 0xffffffff
- Debug: 56692 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 11 mode Supervisor with value 0xffffffff
- Debug: 56693 3980822 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 12 mode Supervisor with value 0xffffffff
- Debug: 56694 3980822 arm7_9_common.c:1638 arm7_9_restore_context(): examining Supervisor mode
- Debug: 56695 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: pc
- Debug: 56696 3980822 arm7_9_common.c:1638 arm7_9_restore_context(): examining Supervisor mode
- Debug: 56697 3980822 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: pc
- Debug: 56698 3980822 arm7_9_common.c:1638 arm7_9_restore_context(): examining Supervisor mode
- Debug: 56699 3980823 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: sp_svc
- Debug: 56700 3980823 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: lr_svc
- Debug: 56701 3980823 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: pc
- Debug: 56702 3980823 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 13 mode Supervisor with value 0xffffffff
- Debug: 56703 3980823 arm7_9_common.c:1704 arm7_9_restore_context(): writing register 14 mode Supervisor with value 0xffffffff
- Debug: 56704 3980823 arm7_9_common.c:1638 arm7_9_restore_context(): examining Supervisor mode
- Debug: 56705 3980823 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: pc
- Debug: 56706 3980823 arm7_9_common.c:1638 arm7_9_restore_context(): examining Supervisor mode
- Debug: 56707 3980823 arm7_9_common.c:1652 arm7_9_restore_context(): examining dirty reg: pc
- Debug: 56708 3980823 arm7_9_common.c:1738 arm7_9_restore_context(): writing cpsr with value 0x200000d3
- Debug: 56709 3980823 arm7tdmi.c:414 arm7tdmi_write_xpsr(): xpsr: 200000d3, spsr: 0
- Debug: 56710 3980823 arm7_9_common.c:1748 arm7_9_restore_context(): writing PC with value 0x00000000
- Debug: 56711 3980823 embeddedice.c:501 embeddedice_write_reg(): 9: 0xffffffff
- Debug: 56712 3980823 embeddedice.c:501 embeddedice_write_reg(): 11: 0xffffffff
- Debug: 56713 3980823 embeddedice.c:501 embeddedice_write_reg(): 12: 0x00000100
- Debug: 56714 3980823 embeddedice.c:501 embeddedice_write_reg(): 13: 0x00000077
- Debug: 56715 3980823 embeddedice.c:501 embeddedice_write_reg(): 16: 0x00000000
- Debug: 56716 3980823 embeddedice.c:501 embeddedice_write_reg(): 17: 0x00000000
- Debug: 56717 3980823 embeddedice.c:501 embeddedice_write_reg(): 19: 0xffffffff
- Debug: 56718 3980823 embeddedice.c:501 embeddedice_write_reg(): 20: 0x00000000
- Debug: 56719 3980823 embeddedice.c:501 embeddedice_write_reg(): 21: 0x000000f7
- Debug: 56720 3980823 target.c:1062 target_call_event_callbacks(): target event 4 (resumed)
- Debug: 56721 3980849 embeddedice.c:501 embeddedice_write_reg(): 9: 0x00000003
- Debug: 56722 3980849 embeddedice.c:501 embeddedice_write_reg(): 11: 0xffffffff
- Debug: 56723 3980849 embeddedice.c:501 embeddedice_write_reg(): 12: 0x00000000
- Debug: 56724 3980849 embeddedice.c:501 embeddedice_write_reg(): 13: 0x000000f7
- Debug: 56725 3980849 embeddedice.c:501 embeddedice_write_reg(): 16: 0x00000000
- Debug: 56726 3980849 embeddedice.c:501 embeddedice_write_reg(): 17: 0x00000000
- Debug: 56727 3980849 embeddedice.c:501 embeddedice_write_reg(): 19: 0x00000000
- Debug: 56728 3980849 embeddedice.c:501 embeddedice_write_reg(): 21: 0x00000000
- Debug: 56729 3980849 embeddedice.c:501 embeddedice_write_reg(): 20: 0x00000000
- Debug: 56730 3980849 embeddedice.c:501 embeddedice_write_reg(): 0: 0x00000005
- Debug: 56731 3980849 embeddedice.c:501 embeddedice_write_reg(): 12: 0x00000000
- Debug: 56732 3980851 arm7_9_common.c:1410 arm7_9_debug_entry(): target entered debug from ARM state
- Debug: 56733 3980866 armv4_5.c:397 arm_set_cpsr(): set CPSR 0x200000d3: Supervisor mode, ARM state
- Debug: 56734 3980866 arm7_9_common.c:1438 arm7_9_debug_entry(): target entered debug state in Supervisor mode
- Debug: 56735 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r0: 0xffffffff
- Debug: 56736 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r1: 0xffffffff
- Debug: 56737 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r2: 0xffffffff
- Debug: 56738 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r3: 0xffffffff
- Debug: 56739 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r4: 0xffffffff
- Debug: 56740 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r5: 0xffffffff
- Debug: 56741 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r6: 0xffffffff
- Debug: 56742 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r7: 0xffffffff
- Debug: 56743 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r8: 0xffffffff
- Debug: 56744 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r9: 0xffffffff
- Debug: 56745 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r10: 0xffffffff
- Debug: 56746 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r11: 0xffffffff
- Debug: 56747 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r12: 0xffffffff
- Debug: 56748 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r13: 0xffffffff
- Debug: 56749 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r14: 0xffffffff
- Debug: 56750 3980866 arm7_9_common.c:1460 arm7_9_debug_entry(): r15: 0x001100f0
- Debug: 56751 3980866 arm7_9_common.c:1468 arm7_9_debug_entry(): entered debug state at PC 0x1100f0
- Debug: 56752 3980870 target.c:1062 target_call_event_callbacks(): target event 2 (gdb-halt)
- Debug: 56753 3980870 target.c:1062 target_call_event_callbacks(): target event 3 (halted)
- Debug: 56754 3980870 target.c:1062 target_call_event_callbacks(): target event 8 (gdb-end)
- Debug: 56755 3980870 arm7_9_common.c:2121 arm7_9_step(): target stepped
- Debug: 56756 3980872 gdb_server.c:2201 gdb_input_inner(): received packet: 'g'
- Debug: 56757 3980873 gdb_server.c:2201 gdb_input_inner(): received packet: 'm1100f0,4'
- Debug: 56758 3980873 gdb_server.c:1278 gdb_read_memory_packet(): addr: 0x001100f0, len: 0x00000004
- Debug: 56759 3980873 target.c:1443 target_read_buffer(): reading buffer of 4 byte at 0x001100f0
- Debug: 56760 3980873 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0x001100f0, size: 0x00000004, count: 0x00000001
- Debug: 56761 3980885 gdb_server.c:2201 gdb_input_inner(): received packet: 'mffffffff,4'
- Debug: 56762 3980885 gdb_server.c:1278 gdb_read_memory_packet(): addr: 0xffffffff, len: 0x00000004
- Debug: 56763 3980885 target.c:1443 target_read_buffer(): reading buffer of 4 byte at 0xffffffff
- Error: 56764 3980885 target.c:1460 target_read_buffer(): address + size wrapped(0xffffffff, 0x00000004)
- Using only OpenOCD commands, the we get the following weirdness:
- (gdb) mon reg pc 0
- pc (/32): 0x00000000
- (gdb) mon step
- target state: halted
- target halted in ARM state due to single-step, current mode: Supervisor
- cpsr: 0x200000d3 pc: 0x001100f0
- Entry: ARM assembler cheat sheet
- Date: Wed Jun 22 03:17:19 CEST 2011
- - destination register is on the left
- - s suffix means "update condition flags", i.e. and vs. ands
- [1] http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001m/QRC0001_UAL.pdf
- Entry: AT91SAM7S slow_reset init/halt work again
- Date: Wed Jun 22 04:11:41 CEST 2011
- With openocd e7c611deeac63e585eb61d6c4cdb54d078c2c579 the previous
- trouble[1] I had with reset not working properly seem to be resolved.
- However, it does seem to need the slow_reset.
- [1] entry://20110607-234734
- Entry: Reset to 0x110070 : warm_reset
- Date: Thu Jun 23 13:34:12 CEST 2011
- I find that when I call soft_reset_halt, the PC gets reset to
- 0x110070, which in my current eCos setup is warm_reset. It would be
- strange that this is a coincidence. So how does GDB know how to set
- that address?
- Entry: OpenOCD: reset halt vs. reset init
- Date: Thu Jun 23 13:37:11 CEST 2011
- If the target under debug gets switched off while a debug setting is
- running, issuing a "reset halt" isn't enough. I verfied this and I
- got faulty JTAG communication, but "poll" did work. After "reset
- init" things are back to normal.
- (gdb) mon slow_reset halt
- 100 kHz
- srst pulls trst - can not reset into halted mode. Issuing halt after reset.
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x200000d3 pc: 0x00005bb8
- 1000 kHz
- (gdb) mon poll
- background polling: on
- TAP: at91sam7s256.cpu (enabled)
- target state: halted
- target halted in ARM state due to debug-request, current mode: Supervisor
- cpsr: 0x200000d3 pc: 0x00005bb8
- (gdb) vstepi
- Bad value '00000001' captured during DR or IR scan:
- check_value: 0x00000009
- check_mask: 0x00000009
- JTAG error while reading cpsr
- Bad value '00000001' captured during DR or IR scan:
- check_value: 0x00000009
- check_mask: 0x00000009
- JTAG error while reading cpsr
- Couldn't calculate PC of next instruction, current opcode was 0x00000000
- 0x00005bb8 in ?? ()
- 0x5bb0: andeq r0, r0, r0
- 0x5bb4: andeq r0, r0, r0
- => 0x5bb8: andeq r0, r0, r0
- 0x5bbc: andeq r0, r0, r0
- 0x5bc0: andeq r0, r0, r0
- 0x5bc4: andeq r0, r0, r0
- 0x5bc8: andeq r0, r0, r0
- 0x5bcc: andeq r0, r0, r0
- 0x5bd0: andeq r0, r0, r0
- 0x5bd4: andeq r0, r0, r0
- Entry: AT91SAM7 and reset
- Date: Thu Jun 23 13:53:25 CEST 2011
- Some notes about using OpenOCD on the AT91SAM7 platform. These notes
- reflect behaviour with a recent OpenOCD git version and using the
- ARM-USB-OCD programmer.
- 1. Lower clock when requesting a reset. I can get a reliable reset
- when I lower the clock to 100kHz. Higher than that gives
- problems. Other commands give no problems if ARM clock is set to
- fast. Flash is independent of ARM.
- 2. The AT91SAM7 can't reset in halt, which means that it _will_
- execute code in Flash before any JTAG debugger can halt the chip.
- Therefore it's best to use soft_reset_halt whenever possible and
- use "reset init" only when JTAG gets out of sync, i.e. when target
- is power-cycled.
- Entry: gdb can't connect if target error
- Date: Thu Jun 23 14:21:52 CEST 2011
- It might be best to modify such that gdb is allowed to connect such
- that it can issue a "mon reset init" command.
- Error: Target not halted
- Error: auto_probe failed
- Error: Connect failed. Consider setting up a gdb-attach event for the target to prepare target for GDB connect, or use 'gdb_memory_map disable'.
- Error: attempted 'gdb' connection rejected
- That error is printed in server.c when (abstractly) ->new_connection()
- fails. The implementation of that function is in gdb_server.c :
- static int gdb_new_connection(struct connection *connection);
- The cause seems to be this:
- Connect must fail if the memory map can't be set up correctly.
- Maybe this should trigger some retry somewhere?
- To switch off memory map[1]:
- gdb_memory_map disable
- but of course you can't do this from the gdb side..
- Some more info about that particular patch here[2]. So it's probably
- not a good idea to start prodding there, but to use the `gdb-attach'
- event instead.
- [1] http://www.amontec.com/openocd/doc/GDB-and-OpenOCD.html
- [2] http://www.mail-archive.com/[email protected]/msg13048.html
- [3] entry://20110624-000503
- Entry: stepi ignored. GDB will now fetch the register state from the target.
- Date: Thu Jun 23 14:35:35 CEST 2011
- I read in the code, and it seems that this is a workaround in OpenOCD:
- stepi ignored. GDB will now fetch the register state from the target.
- Before I needed to work around that workaround by adding a harmless
- "stepi" instruction to cancel the ignored stepi.
- So what is this about really?
- From gdbserver.c:
- } else if ((packet[0] == 's') && gdb_con->sync)
- {
- /* Hmm..... when you issue a continue in GDB, then a "stepi" is
- * sent by GDB first to OpenOCD, thus defeating the check to
- * make only the single stepping have the sync feature...
- */
- nostep = true;
- LOG_WARNING("stepi ignored. GDB will now fetch the register state from the target.");
- }
- gdb_con->sync = false;
- Entry: arm.run
- Date: Thu Jun 23 14:39:51 CEST 2011
- #!/bin/bash
- # --- config
- GDB=arm-eabi-gdb-7.2
- OPENOCD_HOST=openocd
- OPENOCD_PORT=3333
- # --- code
- [ -z "$1" ] && echo "usage: $0 <arm.elf>" && exit 1
- ELF=$1
- # ELF=/home/tom/dbb_trailer/build/out/arm/test-blockmanager
- # LOAD_COMMAND=load
- CMD=`mktemp`
- cat<<EOF >>$CMD
- # Load file for debugging symbols
- file $ELF
- # Connect to OpenOCD
- target remote $OPENOCD_HOST:$OPENOCD_PORT
- # Flash the file if requested.
- echo Flashing...\n
- $LOAD_COMMAND
- # Reset target
- monitor slow_reset init
- # Give a couple of harmless instruction step commands starting from
- # the boot vector. The first stepi is a workaround for this:
- #
- # stepi ignored. GDB will now fetch the register state from the target.
- #
- # which is a GDB bug workaround in OpenOCD, preventing the app from
- # starting on a "continue". The subsequent ones are a workaround for
- # an old sync problem that seems to have disappeared.
- stepi
- stepi
- stepi
- # Run until the test is done
- thbreak cyg_test_exit
- continue
- # Cleanup & exit
- shell rm $CMD
- quit
- EOF
- exec $GDB --command=$CMD
- Entry: OpenOCD hacking
- Date: Thu Jun 23 14:47:31 CEST 2011
- - add some exit mechanism to allow for a full restart
- - "stepi ignored"
- - gdb can't connect if probe fails (fixed: use gdb-attach -> reset init)
- - what determines the PC after load/reset? (ELF has entry point set)
- Entry: ARM ELF Entry point
- Date: Thu Jun 23 21:31:46 CEST 2011
- It looks like load sets the entry point. I.e. for my app the PC is
- set to 0x110040. Where is that data stored? Using readelf it can be
- retrieved:
- $ arm-eabi-readelf -h <elf>
- ELF Header:
- Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
- Class: ELF32
- Data: 2's complement, little endian
- Version: 1 (current)
- OS/ABI: UNIX - System V
- ABI Version: 0
- Type: EXEC (Executable file)
- Machine: ARM
- Version: 0x1
- Entry point address: 0x110040
- Start of program headers: 52 (bytes into file)
- Start of section headers: 981516 (bytes into file)
- Flags: 0x4000002, has entry point, Version4 EABI
- Size of this header: 52 (bytes)
- Size of program headers: 32 (bytes)
- Number of program headers: 2
- Size of section headers: 40 (bytes)
- Number of section headers: 21
- Section header string table index: 18
- According to [1] it's at the start of the file even:
- $ hd example-format |head -n 2
- 00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
- 00000010 02 00 28 00 01 00 00 00 40 00 11 00 34 00 00 00 |..([email protected]|
- ^^^^^^^^^^^
- [1] http://vx.netlux.org/lib/static/vdat/tuunix02.htm
- Entry: OpenOCD gdb-attach event
- Date: Fri Jun 24 00:05:03 CEST 2011
- # Reset target when gdb connects. OpenOCD disconnects when a memory
- # map is requested and it can't provide it because target comm is not
- # setup correctly.
- at91sam7s256.cpu configure -event gdb-attach {
- echo "Reset on gdb-attach."
- slow_reset init
- }
- [1] http://openocd.berlios.de/doc/html/CPU-Configuration.html
- Entry: Cannot access memory at address 0xffffffff
- Date: Fri Jun 24 00:55:12 CEST 2011
- I get this error after many commands, including "set $pc = 0".
- Seems to be because GDB requests that address. I don't know where it
- comes from. When an image file is loaded it doesn't seem to be a
- problem.
- Switching on debug_level 3, the correct operation is:
- Debug: 167 336068 gdb_server.c:2201 gdb_input_inner(): received packet: 'g'
- Debug: 168 336068 gdb_server.c:2201 gdb_input_inner(): received packet: 'm0,4'
- Debug: 169 336068 gdb_server.c:1278 gdb_read_memory_packet(): addr: 0x00000000, len: 0x00000004
- Debug: 170 336068 target.c:1443 target_read_buffer(): reading buffer of 4 byte at 0x00000000
- Debug: 171 336068 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0x00000000, size: 0x00000004, count: 0x00000001
- Actually this skips the register set operation, probably because the
- $pc is already set to 0. A register set looks like this:
- Debug: 241 552998 gdb_server.c:2201 gdb_input_inner(): received packet: 'Pf=00000000'
- Debug: 242 552998 gdb_server.c:1198 gdb_set_register_packet(): -
- However, when there is no image loaded, GDB tries to read from 0xFFFFFFFF.
- Debug: 567 761913 gdb_server.c:2201 gdb_input_inner(): received packet: 'mffffffff,1'
- Debug: 568 761913 gdb_server.c:1278 gdb_read_memory_packet(): addr: 0xffffffff, len: 0x00000001
- Debug: 569 761913 target.c:1443 target_read_buffer(): reading buffer of 1 byte at 0xffffffff
- Debug: 570 761913 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0xffffffff, size: 0x00000001, count: 0x00000001
- Debug: 571 761916 gdb_server.c:2201 gdb_input_inner(): received packet: 'g'
- Debug: 572 761916 gdb_server.c:2201 gdb_input_inner(): received packet: 'm0,4'
- Debug: 573 761916 gdb_server.c:1278 gdb_read_memory_packet(): addr: 0x00000000, len: 0x00000004
- Debug: 574 761916 target.c:1443 target_read_buffer(): reading buffer of 4 byte at 0x00000000
- Debug: 575 761916 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0x00000000, size: 0x00000004, count: 0x00000001
- Debug: 576 761918 gdb_server.c:2201 gdb_input_inner(): received packet: 'mffffffff,1'
- Debug: 577 761918 gdb_server.c:1278 gdb_read_memory_packet(): addr: 0xffffffff, len: 0x00000001
- Debug: 578 761918 target.c:1443 target_read_buffer(): reading buffer of 1 byte at 0xffffffff
- Debug: 579 761918 arm7_9_common.c:2270 arm7_9_read_memory(): address: 0xffffffff, size: 0x00000001, count: 0x00000001
- Entry: gdb and low-level debugging
- Date: Fri Jun 24 15:04:14 CEST 2011
- Seems that GDB is really a source debugger. I.e. the "disassemble"
- command can't be used on bare code. For that you need the "x" examine
- command, i.e. "x/10i $pc" will examine 10 units of data at $pc and
- interpret them as instructions.
- The next problem I ran into is setting breakpoints at raw instructions
- instead of symbolic labels. Just using "break" or "thbreak" doesn't
- work. Actually it does, it just needs some special syntax[1]
- (mnemonic: code is a dereferenced code pointer).
- break *0x0000f000
- ( Related remark: it's possible to save current breakpoint
- configuration as a script. See "help breakpoints". )
- [1] http://people.cs.uchicago.edu/~bomb154/154/maclabs/gdblab.html
- Entry: gdb variable to register mapping
- Date: Fri Jun 24 17:02:43 CEST 2011
- Is it possible to print the variable->register mapping in gdb?
- Entry: ARM calling conventions
- Date: Fri Jun 24 18:56:56 CEST 2011
- r0-r3 arguments + return value
- r4-r11 local variables (callee must save)
- r12 scratch
- r13 sp
- r14 lr
- r15 pc
- [1] http://en.wikipedia.org/wiki/Calling_convention#ARM
- Entry: Arm and alginment
- Date: Fri Jun 24 20:27:36 CEST 2011
- It's imperative to properly align data storage on ARM. A normal STR
- instruction needs 4-byte align, STRH[1] needs 2-bytes align and STRB
- needs 2-byte.
- Note that it's very easy to make mistakes against this when you start
- liberally casting void pointers to other types. I spent a couple of
- hours tracking down an obscure error that happened only in optimized
- code. Granted, it took so long to find because eCos data exception
- handling just ignored the error, and that stepping through the
- optimized code was nearly impossible due to heavy inlining
- (spaghetti-izing).
- [1] http://www.rz.uni-karlsruhe.de/rz/docs/VTune/reference/INST_STRH.htm
- arm7_9 dcc_downloads enable
- arm7_9 fast_memory_access enable
- Entry: OpenOCD slow? How to fix?
- Date: Mon Jun 27 16:23:00 CEST 2011
- [1] https://lists.berlios.de/pipermail/openocd-development/2011-June/019747.html
- Entry: urjtag
- Date: Mon Jun 27 16:33:31 CEST 2011
- Another JTAG project[1].
- [1] http://urjtag.org/
- Entry: ARM-USB-OCD-H
- Date: Mon Aug 22 10:54:59 CEST 2011
- I'm using a ARM-USB-OCD which is detected:
- Aug 22 10:55:45 zni kernel: [4122071.964298] usb 3-5.3: new full speed USB device using ehci_hcd and address 19
- Aug 22 10:55:45 zni kernel: [4122072.063273] usb 3-5.3: New USB device found, idVendor=15ba, idProduct=0003
- Aug 22 10:55:45 zni kernel: [4122072.063275] usb 3-5.3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
- Aug 22 10:55:45 zni kernel: [4122072.063278] usb 3-5.3: Product: Olimex OpenOCD JTAG
- Aug 22 10:55:45 zni kernel: [4122072.063279] usb 3-5.3: Manufacturer: Olimex
- Aug 22 10:55:45 zni kernel: [4122072.067085] usb 3-5.3: Ignoring serial port reserved for JTAG
- Aug 22 10:55:45 zni kernel: [4122072.071532] ftdi_sio 3-5.3:1.1: FTDI USB Serial Device converter detected
- Aug 22 10:55:45 zni kernel: [4122072.071565] usb 3-5.3: Detected FT2232C
- Aug 22 10:55:45 zni kernel: [4122072.071567] usb 3-5.3: Number of endpoints 2
- Aug 22 10:55:45 zni kernel: [4122072.071569] usb 3-5.3: Endpoint 1 MaxPacketSize 64
- Aug 22 10:55:45 zni kernel: [4122072.071570] usb 3-5.3: Endpoint 2 MaxPacketSize 64
- Aug 22 10:55:45 zni kernel: [4122072.071571] usb 3-5.3: Setting MaxPacketSize 64
- Aug 22 10:55:45 zni kernel: [4122072.071935] usb 3-5.3: FTDI USB Serial Device converter now attached to ttyUSB2
- Plugging in the identically looking ARM-USB-OCD-H however gives:
- Aug 22 10:56:34 zni kernel: [4122120.341738] usb 3-5.3: new high speed USB device using ehci_hcd and address 20
- Aug 22 10:56:34 zni kernel: [4122120.438456] usb 3-5.3: New USB device found, idVendor=15ba, idProduct=002b
- Aug 22 10:56:34 zni kernel: [4122120.438458] usb 3-5.3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
- Aug 22 10:56:34 zni kernel: [4122120.438461] usb 3-5.3: Product: Olimex OpenOCD JTAG ARM-USB-OCD-H
- Aug 22 10:56:34 zni kernel: [4122120.438462] usb 3-5.3: Manufacturer: Olimex
- Aug 22 10:56:34 zni kernel: [4122120.438464] usb 3-5.3: SerialNumber: OLU9Z1AU
- Looks like my kernel is too old. Can't upgrade now, so let's just patch the current version.
- /opt/src/linux-2.6.33.7-rt29/drivers/usb/serial:
- ftdi_so_ids.h:
- #define OLIMEX_ARM_USB_OCD_H_PID 0x002b
- ftdi_sio.c:
- { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_H_PID),
- .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
- With this, and after setting the correct permissions (udev) it worked.
- Had to use gcc-4.4 to compile my kernel though: 2.6.33.7-rt29
- [1] https://lkml.org/lkml/2011/3/9/347
- Entry: eCos boot
- Date: Mon Aug 22 11:53:11 CEST 2011
- => 0x0: ldr pc, [pc, #24] ; 0x20
- 0x4: ldr pc, [pc, #24] ; 0x24
- 0x8: ldr pc, [pc, #24] ; 0x28
- 0xc: ldr pc, [pc, #24] ; 0x2c
- This loads pc with the contents of vectors stored at the addresses
- mentioned in the comments. Why is the offset #24?
- The reason is processor pipeline[1]. The pc is always 8 bytes ahead.
- [1] http://www.keil.com/forum/16417/
- Entry: Loading core files on ARM target
- Date: Wed Jan 4 19:03:30 EST 2012
- wget http://ftp.gnu.org/gnu/gdb/gdb-7.3.1.tar.bz2
- tar xf gdb-7.3.1.tar.bz2
- mkdir -p gdb-7.3.1/build/arm-eabi
- cd gdb-7.3.1/build/arm-eabi
- ../../configure --target=arm-eabi --enable-tui
- make
- sudo cp gdb/gdb /usr/local/bin/arm-eabi-gdb-7.3.1
- ./gdb/corefile.c:77:
- if (core_target == NULL)
- error (_("GDB can't read core files on this machine."));
- Entry: Loading binary code into ram
- Date: Mon Jun 4 12:24:03 EDT 2012
- Basically what I want to do is this:
- - Load a firmware in Flash
- - Load some extra code in Flash / RAM that can call into Flash.
- Entry: Better GDB scripting
- Date: Tue Jun 5 13:36:24 EDT 2012
- I'm finding a lot of interesting things in Staapl about "host RPC",
- where a very limitied target (small PIC uC) can recursively call code
- on a host. It would be nice to get this kind of workflow going in
- GDB.
- Entry: GDB hooks
- Date: Tue Jul 31 17:32:32 EDT 2012
- I want a simple mechanism to check if a certain breakpoint is hit and
- if so, execute a function then continue.
- Entry: OpenOCD
- Date: Fri Nov 30 15:03:26 EST 2012
- Trying again to use OpenOCD on AT91SAM7 board.
- GIT SHA1 1a8223f28b2a459750b6dd9b867f4cec0c14a515
- $ openocd --file interface/arm-usb-ocd.cfg --file target/sam7x256.cfg
- Entry: AT91SAM7 AIC
- Date: Wed Dec 12 12:55:57 EST 2012
- Source (23.6.3)
- 0: FIQ pin
- 1: SIQ system peripheral interrupt lines (system timer, RTC, PMC, MC, ...)
- 2-31: PID2-PID31: embedded user peripheral / external interrupt lines
- What's the difference between system/user peripheral? E.g. PIO is a
- user peripheral. The peripheral identification defined at the product
- level corresponds to the interrupt source number.
- For a peripheral table, see 10.2
- Registers: (* = E/D or S/C)
- AIC_SMR source mode register
- AIC_I*CR interrupt enable/disable command register
- AIC_I*CR interrupt set/clear command register
- AIC_IPR interrupt pending
- AIC_IVR interrupt vector (read signals entry of ISR)
- AIC_IMR interrupt mask
- AIC_ISR current interrupt (p158)
- AIC_CISR nIRQ/nFIQ lines
- fast forcing
- AIC_EOICR end of interrupt command register (to signal exit of ISR)
- AIC_SVRn source vector register n:1-31 (corresponds to AIC_IVR read)
- The basic idea behind the AIC is to extend the ARM's simple
- single-interrupt model to a multi-priority interrupt model by running
- bulk of the ISR routines with arm IRQ enabled.
- AIC enables fast vectored dispatch to allow for lower interrupt
- latencies. For such routines, care needs to be taken to complete the
- AIC entry/exit in each routine. The AIC uses a stack internally to
- keep track of the current interrupt being served. Entry/exit are
- marked by r/w of AIC_IVR and AIC_EOICR.
- [1] http://www.atmel.com/Images/doc6120.pdf
- Entry: Disassembling raw ARM code
- Date: Mon Jul 15 10:00:23 EDT 2013
- Given a binary, how to get a disassembly dump on the command line?
- It seems best to split this in 2 scripts:
- - convert .bin -> arm .elf with .text section
- - run objdump
- arm-none-eabi-objcopy --input binary --output elf32-littlearm --binary-architecture arm --rename-section .data=.text in.bin out.elf
- arm-none-eabi-objdump -D out.elf
- Entry: at91lib USB
- Date: Thu Jul 25 17:46:01 EDT 2013
- at91lib is low-level without task switching.
- Caveat: callbacks are invoked from the interrupt handler, so can't
- call any code that depends on work done in the interrupt handler.
- Entry: Disable / Enable interrupts
- Date: Wed Aug 14 14:24:45 EDT 2013
- // disable
- asm("mrs r0, cpsr\n"
- "orr r0,r0,#0x80\n"
- "msr cpsr_c,r0\n"
- "mov r0,#1\n"
- "bx lr\n");
- // enable
- asm("mrs r0, cpsr\n"
- "bic r0,r0,#0x80\n"
- "msr cpsr_c,r0\n"
- "bx lr\n");
- Entry: TI Tiva C Series TM4C123G eval board / EK-TM4C123GXL
- Date: Sat Aug 17 23:49:24 EDT 2013
- Looks like the board[1] has a USB JTAG interface (implemented using a
- second identical micro!). It seems this is a TI-ICDI supported by
- openocd.
- OpenOCD config is here[2].
- ./configure \
- --enable-maintainer-mode \
- --enable-ft2232_libftdi \
- --enable-ti-icdi \
- --enable-jlink
- [1] http://www.ti.com/tool/ek-tm4c123gxl
- [2] http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/279223.aspx
- Entry: Community ARM uC boards
- Date: Fri Aug 23 12:48:22 EDT 2013
- Time has come for "standard" platforms:
- - Arduino Due
- - TI Tiva C Launchpad
- Arduino is interesting because it has a potential of being a real
- standard. I'm not a big fan of the IDE for personal use, but at least
- there is a good patch point into the community as a library provider.
- The TI launchpad is interesting because it is very cheap, and has
- embedded JTAG. Downside is that TI software cannot be freely
- redistributed. Though it does seem to have a eLua port.
- Entry: uClinux
- Date: Sun Aug 25 01:11:19 EDT 2013
- On a STM32F437[1]?
- I see.. That board[2] has 16MB PSRAM.
- Not exactly in the 128kByte range :)
- An article that deals with the question of why one would want to do
- that, given that a chip with MMU is not exactly more expensive, and
- that a M3/M4 is not designed to run over external memory interface
- [3].
- [1] https://www.youtube.com/watch?v=k9kKLjefeHM
- [2] http://www.emcraft.com/products/224
- [3] http://electronicdesign.com/embedded/practical-advice-running-uclinux-cortex-m3m4
- Entry: Building Toolchains
- Date: Fri Aug 30 03:07:31 EDT 2013
- - sat https://github.com/esden/summon-arm-toolchain
- I have one built on 2012-12-5, but according to the above this is no
- longer under development. It refers to https://launchpad.net/gcc-arm-embedded
- - crosstool-ng http://crosstool-ng.org/
- Trying this now.. Failed:
- [ERROR] checking for suffix of object files... configure: error: in `/home/tom/ct-ng/.build/arm-unknown-eabi/build/build-cc-core-pass-2/arm-unknown-eabi/libgcc':
- [ERROR] configure: error: cannot compute suffix of object files: cannot compile
- [ERROR] make[1]: *** [configure-target-libgcc] Error 1
- http://gcc.gnu.org/wiki/FAQ#Configuration_fails_with_.27.27configure:_error:_cannot_compute_suffix_of_object_files:_cannot_compile.27.27._What_is_the_problem.3F
- /home/tom/ct-ng/.build/arm-unknown-eabi/build/build-cc-core-pass-2/arm-unknown-eabi/libgcc/config.log:
- conftest.c: In function 'main':
- conftest.c:12:1: sorry, unimplemented: Thumb-1 hard-float VFP ABI
- Weird.. Should I pick a different float arch?
- Linaro has hardfloat thumb? Trying latest..
- http://crosstool-ng.org/download/ibot-logs/2012-10-07.html
- - cortex m4 hardfloat toolchain:
- https://github.com/prattmic/arm-cortex-m4-hardfloat-toolchain
- Also recommends to look at gcc-arm-embedded
- - https://launchpad.net/gcc-arm-embedded
- GCC dev by ARM employees.
- It does hardfloat:
- [email protected]:/tmp$ ~/gcc-arm-embedded/gcc-arm-none-eabi-4_7-2013q2/bin/arm-none-eabi-gcc -O3 -ffast-math -mfpu=vfp -mfloat-abi=hard -mthumb -mcpu=cortex-m4 -c test.c
- [email protected]:/tmp$ ~/gcc-arm-embedded/gcc-arm-none-eabi-4_7-2013q2/bin/arm-none-eabi-objdump -d test.o
- test.o: file format elf32-littlearm
- Disassembly of section .text:
- 00000000 <test>:
- 0: eddf 7a02 vldr s15, [pc, #8] ; c <test+0xc>
- 4: ee30 0a27 vadd.f32 s0, s0, s15
- 8: 4770 bx lr
- a: bf00 nop
- c: 42f60000 .word 0x42f60000
- So, these options are necessary:
- -mcpu=cortex-m4
- -mthumb enables thumb-2 mode
- -mfloat-abi=hard since not all M4 have hard float
- Entry: Paul Stoffregen
- Date: Tue Sep 3 19:10:13 EDT 2013
- http://www.kickstarter.com/profile/paulstoffregen
- http://www.dorkbotpdx.org/blog/paul
- http://www.youtube.com/user/PaulStoffregen
- https://twitter.com/PaulStoffregen
- Entry: Teensy 3.0 - STM Cortex M4
- Date: Wed Sep 4 20:33:21 EDT 2013
- No JTAG though.. Too bad.
- Looks like it's the TI M4 boards are more interesting at this point.
- http://hackaday.com/2012/09/05/meet-the-teensy-3-0/
- Entry: Trying out Tivaware
- Date: Sat Sep 7 17:12:45 EDT 2013
- With arm-none-eabi-* binaries[1] in the path, things seem to work out
- of the box:
- $ cd tivaware/examples/boards/ek-tm4c123gxl/freertos_demo
- $ make
- $ file gcc/freertos_demo.axf
- gcc/freertos_demo.axf: ELF 32-bit LSB executable, ARM, version 1 (SYSV), statically linked, not stripped
- Let's see if there's a simpler example: blinky.c in:
- $ cd tivaware/examples/boards/ek-tm4c123gxl/blinky
- It has a very simple main file. Where is the chip startup? Ah, in
- startup_gcc.c - check linker flag "--entry ResetISR".
- using blinky.ld, gnu ld links:
- - blinky.o
- - startup_gcc.o
- - libm.a
- - libc.a
- - libgcc.a
- ( Makefile finds libc.a ... using
- arm-none-eabi-gcc print-file-name=libc.a )
- The output .axf is just an ELF.
- The startup_gcc.c file seems to have the "viral" clause license..
- From what I read this is probably not a problem in practice.
- Startup does:
- - ISR vector setup (different than ARMv5 ?)
- - RAM data,bss setup
- - Float unit setup
- - main()
- Let's try to upload it.
- $ openocd --version
- Open On-Chip Debugger 0.8.0-dev-00120-gc93d28d-dirty (2013-08-18-00:30)
- # M-x gdb
- ~/tm4c/gdb -i=mi /opt/xc/tivaware/examples/boards/ek-tm4c123gxl/blinky/gcc/blinky.axf
- After fixing some gdb/emacs problems that required updates, it does
- seem that the "load" command worked as the led is blinking:
- mon reset
- mon halt
- Though there are some problems:
- - first time around, "load" didn't work
- - can't write to PC?
- p $pc
- $5 = (void (*)()) 0x28f <main+35>
- set $pc = 0
- p $pc
- $6 = (void (*)()) 0x1 <g_pfnVectors+1>
- [1] https://launchpad.net/gcc-arm-embedded
- Entry: Cortex M4 boot?
- Date: Sat Sep 7 18:57:58 EDT 2013
- Does a M4 boot differently than an ARM 7 TDMI?
- From [1]: ...the vector table at 0 is actually a table of vectors
- (pointers), not instructions. The first entry contains the
- start-up value for the SP register, the second is the reset
- vector. This allows writing the reset handler directly in C, since
- the processor sets up the stack.
- __Vectors DCD __initial_sp ; Top of Stack
- DCD Reset_Handler ; Reset Handler
- DCD NMI_Handler ; NMI Handler
- DCD HardFault_Handler ; Hard Fault Handler
- DCD MemManage_Handler ; MPU Fault Handler
- DCD BusFault_Handler ; Bus Fault Handler
- DCD UsageFault_Handler ; Usage Fault Handler
- [...more vectors...]
- [1] http://stackoverflow.com/questions/6139952/what-is-the-booting-process-for-arm
- Entry: PC odd addresses?
- Date: Sat Sep 7 19:07:13 EDT 2013
- Why are PC addresses odd?
- It seems this indicates thumb mode.
- [1] http://stackoverflow.com/questions/15764833/indirect-function-call-uses-odd-address
- Entry: Cheat sheet
- Date: Sat Sep 7 19:50:00 EDT 2013
- [1] http://infocenter.arm.com/help/topic/com.arm.doc.qrc0001l/QRC0001_UAL.pdf
- [2] http://simplemachines.it/doc/arm_inst.pdf
- Entry: Cortex M4
- Date: Sat Sep 7 20:44:33 EDT 2013
- http://www.eejournal.com/archives/articles/20100223-cortex/
- Entry: ARM DSP intrinsics
- Date: Sun Sep 8 19:48:05 EDT 2013
- Goes GCC support this? According to [3] it doesn't.
- Does LLVM support it?
- Looks like the general idea is that I'm going to have to do this in
- asm. Maybe this is a good excuse to learn about register allocation
- and some other compiler optimization techniques.
- But first, learn the asm.
- [1] http://www.iar.com/About/Blog/2012/1/Designing-advanced-DSP-applications/
- [2] http://stackoverflow.com/questions/9828567/arm-neon-intrinsics-vs-hand-assembly
- [3] http://stackoverflow.com/questions/14188262/how-to-enable-intrinsics-in-compiler
- Entry: Running Cortex-M4 DSP code on QEMU
- Date: Mon Sep 16 19:50:35 EDT 2013
- The Cortex-M4 is not supported directly. However, it seems that the
- DSP instruction set is supported in ARM mode, at least just using
- arm-none-eabi-gcc on "qadd r1,r2,r3" produces:
- 00000000 <.text>:
- 0: e1031052 qadd r1, r2, r3
- As opposed to "-mcpu=cortex-m4 -mthumb" :
- 00000000 <.text>:
- 0: fa83 f182 qadd r1, r2, r3
- Let's see if qemu in plain arm mode executes the first one.
- ... DSP instructions were added to the set. These are signified by
- an "E" in the name of the ARMv5TE and ARMv5TEJ architectures[1].
- Qemu supports:
- $ qemu-system-arm -cpu ?
- Available CPUs:
- arm1026
- arm1136
- arm1136-r2
- arm1176
- arm11mpcore
- arm926
- arm946
- cortex-a15
- cortex-a8
- cortex-a9
- cortex-m3
- pxa250
- pxa255
- pxa260
- pxa261
- pxa262
- pxa270-a0
- pxa270-a1
- pxa270
- pxa270-b0
- pxa270-b1
- pxa270-c0
- pxa270-c5
- sa1100
- sa1110
- ti925t
- any
- For GCC it's -mcpu=name:
- This specifies the name of the target ARM processor. GCC uses this
- name to determine what kind of instructions it can emit when
- generating assembly code. Permissible names are: arm2, arm250,
- arm3, arm6, arm60, arm600, arm610, arm620, arm7, arm7m, arm7d,
- arm7dm, arm7di, arm7dmi, arm70, arm700, arm700i, arm710, arm710c,
- arm7100, arm720, arm7500, arm7500fe, arm7tdmi, arm7tdmi-s, arm710t,
- arm720t, arm740t, strongarm, strongarm110, strongarm1100,
- strongarm1110, arm8, arm810, arm9, arm9e, arm920, arm920t, arm922t,
- arm946e-s, arm966e-s, arm968e-s, arm926ej-s, arm940t, arm9tdmi,
- arm10tdmi, arm1020t, arm1026ej-s, arm10e, arm1020e, arm1022e,
- arm1136j-s, arm1136jf-s, mpcore, mpcorenovfp, arm1156t2-s,
- arm1156t2f-s, arm1176jz-s, arm1176jzf-s, cortex-a5, cortex-a7,
- cortex-a8, cortex-a9, cortex-a15, cortex-r4, cortex-r4f, cortex-r5,
- cortex-m4, cortex-m3, cortex-m1, cortex-m0, xscale, iwmmxt, iwmmxt2,
- ep9312, fa526, fa626, fa606te, fa626te, fmp626, fa726te.
- So, pick the simplest one with an 'E' in it. Don't want an elaborate
- boot massaging process..
- Maybe -cpu=any is good for qemu?
- So both cortex-a8 and cortex-a9 seem to work in ARM and THUMB mode.
- [1] http://en.wikipedia.org/wiki/ARM_architecture#DSP_enhancement_instructions
- Entry: Semihosting exit
- Date: Mon Sep 16 20:51:14 EDT 2013
- Semihisting SYS_EXIT. See [1].
- [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-08/msg03889.html
- Entry: Inline asm
- Date: Mon Sep 16 21:32:15 EDT 2013
- [1] http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
- Entry: DSP instructions
- Date: Mon Sep 16 21:41:51 EDT 2013
- saturating and multiply instructions:
- http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/Cihddjgg.html
- http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/Cihjfeii.html
- Entry: M0 vs M3
- Date: Thu Sep 19 20:25:40 EDT 2013
- Asked when someone might need to move to 32bit from 8 or 16bit, York
- said, “The protocol stack for ZigBee is atrocious on an 8bit
- core. It is the same with USB and Bluetooth, and if an ADC is 16bit,
- you are going to want 32bits to manipulate the data without
- overflowing.â€
- http://www.electronicsweekly.com/news/components/microprocessors-and-dsps/arms-cortex-m0-processor-how-it-works-2009-03/
- Entry: Debian on Beagleboard xM
- Date: Thu Sep 26 18:43:31 EDT 2013
- Got debian installed through:
- http://elinux.org/BeagleBoardDebian
- 2013-08-26 image
- Though there are problems when netload gets high: USB gives up.
- ( Board has ethernet connector setup through USB instead of the SoC. )
- Found a couple of references to this:
- https://groups.google.com/forum/#!topic/beagleboard/ji8SiHrzC2Y
- How to solve?
- EDIT: Might just be power supply. I had it powered over USB, but it
- probably takes more than 500mA. It seems to run fine on a 2A DC
- adapter.
- Entry: qemu osmocom
- Date: Sun Nov 24 08:39:45 EST 2013
- http://git.osmocom.org/qemu
- Trouble with texinfo 5.2, so doing this:
- ./configure --disable-docs --disable-user --target-list=arm-softmmu
- In the diff I see no reference to any command line flag that enables
- this particular machine. What does `machine_init' do?
- Also patch config-host.mak:
- Add -lrt to LIBS_QGQ and LIBS
- remove -Werror from QEMU_CFLAGS
- compiles.. result is in
- arm-softmmu/qemu-system-arm
- now how does that extension work?
- Start with this:
- static void cc32_register_types(void)
- {
- type_register_static(&cc32_sysc_info);
- type_register_static(&cc32_flcon_info);
- }
- type_init(cc32_register_types)
- Entry: qemu primer
- Date: Sun Nov 24 10:23:47 EST 2013
- - modules are registered through init functions defined in module.h :
- #define block_init(function) module_init(function, MODULE_INIT_BLOCK)
- #define machine_init(function) module_init(function, MODULE_INIT_MACHINE)
- #define qapi_init(function) module_init(function, MODULE_INIT_QAPI)
- #define type_init(function) module_init(function, MODULE_INIT_QOM)
- Probably best to start reading here:
- http://qemu.weilnetz.de/qemu-tech.html
- http://wiki.qemu.org/Documentation/GettingStartedDevelopers
- Starting from the CC32RS512 diff, it might be good to add a memory
- mapped I/O for debug output. This would give a good idea of how
- virtual devices work.
- Relevant calls/macros for the CC32 SYSC emulation:
- type_init(cc32_register_types)
- type_register_static(&cc32_sysc_info);
- cc32_sysc_class_init()
- DEVICE_CLASS()
- SYS_BUS_DEVICE_CLASS()
- cc32_sysc_init
- cc32_sysc_reset
- FROM_SYSBUS()
- qdev_init_gpio_in()
- sysbus_init_irq()
- memory_region_init_io()
- sysbus_init_mmio()
- container_of()
- sysbus_create_varargs() / sysbus_create_simple()
- Datastructures first.
- static void cc32_sysc_reset(DeviceState *d) {
- cc32_sysc_state *s = container_of(d, cc32_sysc_state, busdev.qdev);
- ...
- }
- This recovers larger scope for "inlined" C data structures,
- i.e. find s such that &(s->busdev.qdev) == d
- This avoids having to store back-pointers.
- struct cc32_sysc_state {
- ...
- SysBusDevice busdev;
- ...
- };
- struct SysBusDevice {
- ...
- DeviceState qdev;
- ...
- };
- Entry: Qemu minimal build
- Date: Fri Dec 6 10:09:16 EST 2013
- FIXME: Tried a from scratch LXC Debian wheezy VM. Doesn't seem to
- have the necessary packages..
- Minimal build for ARM embedded dev.
- apt-get install libpixman-1-dev pkg-config libz-dev libglib2.0-dev
- ./configure --disable-docs --disable-user --target-list=arm-softmmu
- [1] http://www.linuxforu.com/2011/06/qemu-for-embedded-systems-development-part-1/
- Entry: Minimal qemu
- Date: Fri Dec 6 11:45:25 EST 2013
- ## list of things to disable
- # ./configure --help |grep disable |awk -e '{print $1}'
- # ./configure --help|grep list
- ## Don't disable:
- # --disable-system
- ./configure --target-list=arm-softmmu \
- --audio-drv-list= \
- --audio-card-list= \
- --disable-debug-tcg \
- --disable-sparse \
- --disable-strip \
- --disable-werror \
- --disable-sdl \
- --disable-virtfs \
- --disable-vnc \
- --disable-xen \
- --disable-brlapi \
- --disable-vnc-tls \
- --disable-vnc-sasl \
- --disable-vnc-jpeg \
- --disable-vnc-png \
- --disable-vnc-thread \
- --disable-curses \
- --disable-curl \
- --disable-fdt \
- --disable-bluez \
- --disable-slirp \
- --disable-kvm \
- --disable-nptl \
- --disable-system \
- --disable-user \
- --disable-linux-user \
- --disable-darwin-user \
- --disable-bsd-user \
- --disable-guest-base \
- --disable-pie \
- --disable-uuid \
- --disable-vde \
- --disable-linux-aio \
- --disable-cap-ng \
- --disable-attr \
- --disable-blobs \
- --disable-docs \
- --disable-vhost-net \
- --disable-spice \
- --disable-libiscsi \
- --disable-smartcard \
- --disable-smartcard-nss \
- --disable-usb-redir \
- --disable-guest-agent
- Entry: set $pc = 0 on ARM7TMDI
- Date: Fri Dec 6 12:58:42 EST 2013
- About the ARM pipeline. This is a bit confusing. It's interesting
- how this confusion has lasted so long..
- Up to this point I seem to recall always reading asm code such that
- the current $pc -- annotated by '=>' in asm dump (e.g. x/10i) --
- points to the current instruction. However, the instruction that's
- executing is actually 3 instructions back.
- Now the funny thing is that r1 after this:
- mov r1, pc
- is 20 (0x14) bytes past the address of the instruction. How is that?
- The reason might be that qemu is not emulating the ARM7TDMI but is
- using -cpu arm926 by default. It seems that pc-relative addressing is
- standardized across designs with different pipeline depths, but
- register moves are not?
- 20 bytes is 5 instructions. Is this the 5-stage pipeline? Shouln't
- it be one byte less in that case?
- Entry: Adding a register-mapped QEMU device
- Date: Sat Dec 7 09:50:54 EST 2013
- 1. Build system
- Create file hw/zwizwa.c
- Add a reference to Makefile.target:
- obj-arm-y += zwizwa.o
- 2. In .c file, register objects:
- #include <stdio.h>
- #include "module.h"
- static void zwizwa_register_types(void) {
- printf("zwizwa_register_types\n");
- }
- type_init(zwizwa_register_types)
- 3. Call type_register_static on TypInfo struct
- #include "module.h"
- #include "sysbus.h"
- #include "qemu/object.h"
- typedef struct {
- } zwizwa_debug_state;
- static void zwizwa_debug_class_init(ObjectClass *klass, void *data) {
- }
- static TypeInfo zwizwa_debug_info = {
- .name = "zwizwa-debug",
- .parent = TYPE_SYS_BUS_DEVICE,
- .instance_size = sizeof(zwizwa_debug_state),
- .class_init = zwizwa_debug_class_init,
- };
- static void zwizwa_register_types(void) {
- type_register_static(&zwizwa_debug_info);
- }
- type_init(zwizwa_register_types)
- 4. Implement ObjectClass init method
- This needs a little explanation of the class system. What I can
- gather, the hierarchy is:
- object -> device -> sys-bus-device
- For this type, there are two methods to register:
- static int zwizwa_debug_init(SysBusDevice *dev){
- return 0;
- }
- static void zwizwa_debug_reset(DeviceState *d){
- }
- static void zwizwa_debug_class_init(ObjectClass *klass, void *data) {
- DeviceClass *dc = DEVICE_CLASS(klass);
- SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
- sdc->init = zwizwa_debug_init;
- dc->reset = zwizwa_debug_reset;
- }
- Here DEVICE_CLASS() and SYS_BUS_DEVICE_CLASS() are dynamic casts with
- type checking:
- #define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
- #define TYPE_DEVICE "device"
- #define OBJECT_CLASS(class) ((ObjectClass *)(class))
- #define OBJECT_CLASS_CHECK(class, obj, name) \
- ((class *)object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name)))
- with object_ function implemented in object.c
- That file seems to be quite recent:
- * Copyright IBM, Corp. 2011
- *
- * Authors:
- * Anthony Liguori <[email protected]>
- *
- 5. Nested objects
- From the use of container_of(), it seems that much of QEMU's data
- structures are organized as composite flat objects (as opposed to
- objects pointing to other objects). I'm guessing this macro
- originates in the Linux source[1].
- Using a flat representation makes ownership relationships very clear
- and makes it possible to traverse the structure hierarchy in two
- directions without extra bookkeeping (e.g. reverse pointers).
- - down: C structure member dereference
- - up: container_of(member_ptr, parent_type, member_name)
- 6. Access to objects in init / reset.
- static int zwizwa_debug_init(SysBusDevice *dev){
- zwizwa_debug_state *s = FROM_SYSBUS(typeof(*s), dev);
- // ...
- return 0;
- }
- static void zwizwa_debug_reset(DeviceState *d){
- zwizwa_debug_state *s = container_of(d, typeof(*s), busdev.qdev);
- // ...
- }
- From the CC32RS512 example, the FROM_SYSBUS macro is used to convert a
- SysBusDevice pointer to the full object. Note that this is also a
- container_of() style macro.
- #define FROM_SYSBUS(type, dev) DO_UPCAST(type, busdev, dev)
- #define DO_UPCAST(type, field, dev) container_of(dev, type, field)
- In the FROM_SYSBUS definition, the field name "busdev" is fixed, so we
- need to make sure we have that in our state structure:
- typedef struct zwizwa_debug_state {
- SysBusDevice busdev;
- }
- Actually, this seems deprecated[2]: use your own macro based on OBJECT_CHECK()
- For reset, need to know that this is a device method, so we go up one
- more in the hierarchy.
- 7. Implement init / reset.
- Some relevant calls from the CC32RS512 module:
- qdev_init_gpio_in()
- memory_region_init_io()
- sysbus_init_irq()
- sysbus_init_mmio()
- For this example we only use memory mapped io:
- typedef struct {
- SysBusDevice busdev;
- MemoryRegion iomem;
- } zwizwa_debug_state;
- static uint64_t zwizwa_debug_read(void *opaque, target_phys_addr_t offset, unsigned size) {
- return 0;
- }
- static void zwizwa_debug_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size) {
- printf("%08x <- %08x\n", (unsigned int)offset, (unsigned int)value);
- }
- static const MemoryRegionOps zwizwa_debug_ops = {
- .read = zwizwa_debug_read,
- .write = zwizwa_debug_write,
- .endianness = DEVICE_NATIVE_ENDIAN,
- };
- static int zwizwa_debug_init(SysBusDevice *dev){
- zwizwa_debug_state *s = FROM_SYSBUS(typeof(*s), dev);
- memory_region_init_io(&s->iomem, &zwizwa_debug_ops, s, "zwizwa-debug", 4);
- sysbus_init_mmio(dev, &s->iomem);
- return 0;
- }
- 8. Instantiate
- Called from machine init:
- sysbus_create_varargs("zwizwa-debug", 0x0FF000, NULL);
- [1] http://stackoverflow.com/questions/15832301/understanding-container-of-macro-in-linux-kernel
- [2] http://osdir.com/ml/qemu-devel/2013-07/msg05332.html
- Entry: QEMU i/o write prob
- Date: Sat Dec 7 12:26:08 EST 2013
- Somehow the code above doesn't work.. Time to trace it.
- It works from ASM:
- mov r0, #0x10000
- str r0, [r0]
- But not from GDB:
- (gdb) set *0x10000 = 123
- Weird.. Is this a qemu gdb stub problem? Let's trace it down.
- In gdbstub.c everything goes through:
- target_memory_rw_debug()
- which calls:
- cpu_memory_rw_debug() in exec.c line 4527
- it's because is_ram_rom_romd() returns false
- Qs:
- - should is_ram_rom_romd() return true for i/o memory?
- - why does it return different values for 2 separate calls? -> it doesn't
- it seems i/o memory is simply excluded in gdbstub
- Entry: libfdt
- Date: Sat Dec 7 13:33:55 EST 2013
- device tree compiler
- http://ozlabs.org/~dgibson/
- Entry: GDB stepping on qemu VM.
- Date: Sat Dec 7 14:15:11 EST 2013
- Something isn't right...
- Tried with more recent QEMU and it doesn't seem to have this problem.
- It executs the instruction at $pc, not the one 3 instructions back
- It would be interesting to find out on the mailing list what exactly
- happened here..
- Conclusion is that single-stepping an ARM doesn't seem so well-defined!
- Last merge was:
- 2012-03-03 5a30d3f19d9c6d135bf7a395a24dc455698d5cf9
- That's a lot of patches.. Cursory glance didn't find antying.
- Hmmm... I wonder if I just disabled it?
- Entry: Moving to new QEMU
- Date: Sat Dec 7 15:26:45 EST 2013
- Some things have shifted around since 2012-03-03.
- Probably best to first merge the zwizwa stuff, then merge the
- CC32RS512.
- EDIT: zwizwa stuff done.
- Tried the pipeline thing and now both instructions have pc pointing 2
- instructions ahead. Looks like the previous behavior was just a bug.
- 0x3c <InitReset>: mov r0, pc ; loads 0x44
- => 0x40 <InitReset+4>: ldr r0, [pc] ; 0x48 <InitReset+12>
- Entry: Extending QEMU with a new processor target
- Date: Wed Dec 11 13:14:13 EST 2013
- How to do this? Let's dive into the source:
- target-arm/cpu.c
- static const ARMCPUInfo arm_cpus[] = {
- ...
- { .name = "cortex-m3", .initfn = cortex_m3_initfn,
- .class_init = arm_v7m_class_init },
- ...
- }
- CPU types seem to be factored into feature sets:
- static void cortex_m3_initfn(Object *obj)
- {
- ARMCPU *cpu = ARM_CPU(obj);
- set_feature(&cpu->env, ARM_FEATURE_V7);
- set_feature(&cpu->env, ARM_FEATURE_M);
- cpu->midr = 0x410fc231;
- }
- To simulate the cortex-m4, I have been using the cortex-a8 for its
- support of the thumb2 DSP instruction set. Let's trace that down:
- static void cortex_a8_initfn(Object *obj)
- {
- ARMCPU *cpu = ARM_CPU(obj);
- set_feature(&cpu->env, ARM_FEATURE_V7);
- set_feature(&cpu->env, ARM_FEATURE_VFP3);
- set_feature(&cpu->env, ARM_FEATURE_NEON);
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
- set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
- cpu->midr = 0x410fc080;
- cpu->reset_fpsid = 0x410330c0;
- cpu->mvfr0 = 0x11110222;
- cpu->mvfr1 = 0x00011100;
- cpu->ctr = 0x82048004;
- cpu->reset_sctlr = 0x00c50078;
- cpu->id_pfr0 = 0x1031;
- cpu->id_pfr1 = 0x11;
- cpu->id_dfr0 = 0x400;
- cpu->id_afr0 = 0;
- cpu->id_mmfr0 = 0x31100003;
- cpu->id_mmfr1 = 0x20000000;
- cpu->id_mmfr2 = 0x01202000;
- cpu->id_mmfr3 = 0x11;
- cpu->id_isar0 = 0x00101111;
- cpu->id_isar1 = 0x12112111;
- cpu->id_isar2 = 0x21232031;
- cpu->id_isar3 = 0x11112131;
- cpu->id_isar4 = 0x00111142;
- cpu->clidr = (1 << 27) | (2 << 24) | 3;
- cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
- cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
- cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
- cpu->reset_auxcr = 2;
- define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
- }
- // target-arm/cpu.h
- /* If adding a feature bit which corresponds to a Linux ELF
- * HWCAP bit, remember to update the feature-bit-to-hwcap
- * mapping in linux-user/elfload.c:get_elf_hwcap().
- */
- enum arm_features {
- ARM_FEATURE_VFP,
- ARM_FEATURE_AUXCR, /* ARM1026 Auxiliary control register. */
- ARM_FEATURE_XSCALE, /* Intel XScale extensions. */
- ARM_FEATURE_IWMMXT, /* Intel iwMMXt extension. */
- ARM_FEATURE_V6,
- ARM_FEATURE_V6K,
- ARM_FEATURE_V7,
- ARM_FEATURE_THUMB2,
- ARM_FEATURE_MPU, /* Only has Memory Protection Unit, not full MMU. */
- ARM_FEATURE_VFP3,
- ARM_FEATURE_VFP_FP16,
- ARM_FEATURE_NEON,
- ARM_FEATURE_THUMB_DIV, /* divide supported in Thumb encoding */
- ARM_FEATURE_M, /* Microcontroller profile. */
- ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
- ARM_FEATURE_THUMB2EE,
- ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
- ARM_FEATURE_V4T,
- ARM_FEATURE_V5,
- ARM_FEATURE_STRONGARM,
- ARM_FEATURE_VAPA, /* cp15 VA to PA lookups */
- ARM_FEATURE_ARM_DIV, /* divide supported in ARM encoding */
- ARM_FEATURE_VFP4, /* VFPv4 (implies that NEON is v2) */
- ARM_FEATURE_GENERIC_TIMER,
- ARM_FEATURE_MVFR, /* Media and VFP Feature Registers 0 and 1 */
- ARM_FEATURE_DUMMY_C15_REGS, /* RAZ/WI all of cp15 crn=15 */
- ARM_FEATURE_CACHE_TEST_CLEAN, /* 926/1026 style test-and-clean ops */
- ARM_FEATURE_CACHE_DIRTY_REG, /* 1136/1176 cache dirty status register */
- ARM_FEATURE_CACHE_BLOCK_OPS, /* v6 optional cache block operations */
- ARM_FEATURE_MPIDR, /* has cp15 MPIDR */
- ARM_FEATURE_PXN, /* has Privileged Execute Never bit */
- ARM_FEATURE_LPAE, /* has Large Physical Address Extension */
- ARM_FEATURE_V8,
- ARM_FEATURE_AARCH64, /* supports 64 bit mode */
- };
- What I did not find immediately is where these tags are used in the
- interpretation / compilation.. So let's dive into that first. Where
- are the instructions defined?
- Beef seems to be in target-arm/translate.c
- Lots of functions prefixed "gen_". I guess these are code generators
- for the individual instructions? They call into "tcg_gen_" prefixed
- functions, which is the Tiny Code Generator.
- What are the "disas_" functions? They call into tcg as well.
- Entry: Qemu ARM IRQ
- Date: Thu Dec 12 15:29:19 EST 2013
- This doesn't work any more:
- cpu_irq = arm_pic_init_cpu(env);
- Where to find how this changed?
- Here's the answer [1].
- - pic = arm_pic_init_cpu(s->cpu);
- s->pic = sysbus_create_varargs("strongarm_pic", 0x90050000,
- - pic[ARM_PIC_CPU_IRQ], pic[ARM_PIC_CPU_FIQ], NULL);
- + qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ),
- + qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_FIQ),
- + NULL);
- So in the CC32RS512 code, this is probably what it needs to be: the
- cc32-sysc is connected to the 2 ARM interrupts IRQ and FIQ, and the
- rest of the hardware is connected to the interrupt controller which
- has 32 interrupts.
- dev = DEVICE(cpu);
- dev = sysbus_create_varargs("cc32-sysc", 0x0F0000,
- qdev_get_gpio_in(dev, ARM_CPU_IRQ),
- qdev_get_gpio_in(dev, ARM_CPU_FIQ),
- NULL);
- for (i = 0; i < 32; i++) {
- fprintf(stderr, "PIC %d\n", i);
- pic[i] = qdev_get_gpio_in(dev, i);
- }
- [1] http://lists.nongnu.org/archive/html/qemu-devel/2013-08/msg01080.html
- Entry: Qemu overview
- Date: Fri Dec 13 10:39:06 EST 2013
- High-level and mostly wrong overview of qemu:
- - Asm code gets translated to TCG code, then compiled to native code
- or interpreted.
- - Memory accesses are either based on the RAM/ROM objects, or sysbus objects
- - sysbus objects have behavior associated to read/write. they also
- interact with interrupts.
- - not clear how exactly control flow works for interrupts
- From [1]:
- 2.11 Hardware interrupts
- In order to be faster, QEMU does not check at every basic block if a
- hardware interrupt is pending. Instead, the user must asynchronously
- call a specific function to tell that an interrupt is pending. This
- function resets the chaining of the currently executing basic
- block. It ensures that the execution will return soon in the main
- loop of the CPU emulator. Then the main loop can test if the
- interrupt is pending and handle it.
- - guest code is called synchronously[2]:
- ... what matters is that both TCG and KVM allow us to jump into
- guest code and execute it. Jumping into guest code takes away our
- control of execution and gives control to the guest. While a thread
- is running guest code it cannot simultaneously be in the event loop
- because the guest has (safe) control of the CPU. Typically the
- amount of time spent in guest code is limited because reads and
- writes to emulated device registers and other exceptions cause us to
- leave the guest and give control back to QEMU. In extreme cases a
- guest can spend an unbounded amount of time without giving up
- control and this would make QEMU unresponsive. In order to solve
- the problem of guest code hogging QEMU's thread of control signals
- are used to break out of the guest.
- [1] http://ellcc.org/ellcc/share/doc/qemu/qemu-tech.html#Hardware-interrupts
- [2] http://blog.vmsplice.net/2011/03/qemu-internals-overall-architecture-and.html
- Entry: Why is there no qemu arm7tdmi emulator?
- Date: Fri Dec 13 12:02:25 EST 2013
- From a brief look at the code, patching together a cpu from feature
- sets isn't a big amount of work.
- Maybe have a look at skyeye[1]
- [1] http://balau82.wordpress.com/2010/09/27/simulating-at91-with-skyeye/
- Entry: ARM + high speed usb: SAM3U
- Date: Sat Mar 22 13:37:26 EDT 2014
- [1] http://www.atmel.com/products/microcontrollers/arm/sam3u.aspx
- Entry: Debian multiarch for cross-compilation
- Date: Fri Aug 22 21:30:35 CEST 2014
- sudo sudo dpkg –-add-architecture armel
- It seems this only works with libraries. Can't have both
- cpp-4.9:amd64 and cpp-4.9:armel installed? Is there a way to have
- this conflict resolved?
- [1] http://www.lshift.net/blog/2012/06/17/using-debian-multiarch-for-cross-compiling
- [2] http://lwn.net/Articles/482952/
- Entry: emdebian cross compiler
- Date: Mon Aug 25 18:02:30 CEST 2014
- # deb [arch=amd64] http://ftp.uk.debian.org/emdebian/toolchains stable main
- # deb [arch=amd64] http://ftp.uk.debian.org/emdebian/toolchains testing main
- apt-get install g++-4.7-arm-linux-gnueabi
- Entry: Multiarch cross compilers
- Date: Mon Aug 25 19:46:20 CEST 2014
- How to obtain a cross toolchain that works with installed multiarch
- -dev packages? Prebuilt toolchains are here[2].
- Tried, but currently there is a version gcc-4.9 mismatch in sid wrt[2]
- 4.9.1-9: amd64
- 4.9.1-8: arm64 armel armhf hppa hurd-i386 i386 kfreebsd-amd64 kfreebsd-i386 mipsel powerpc ppc64 s390x sparc x32
- Build one from source?
- [1] https://wiki.debian.org/MultiarchCrossToolchainBuild
- [2] http://toolchains.secretsauce.net/
- Entry: Old way: emdebian xapt
- Date: Mon Aug 25 23:22:53 CEST 2014
- xapt -a armhf -m libusb-1.0-0-dev libboost-filesystem-dev libpython3.4-dev
- This still needs a lot of magic with -I flags and -rpath... How to
- automate? For pratical purposes, I can now compile on target. Maybe
- best to just wait until the multiarch stuff works.
- [1] https://wiki.debian.org/EmdebianToolchain
- Entry: Time to figure out state-of-the-art cross compilers
- Date: Fri Sep 12 21:47:34 CEST 2014
- Bare-metal isn't that hard. Use use binaries from [1] together with
- some multiarch i386 suport:.
- sudo apt-get install libc6:i386 libc6-i686:i386 libgcc1:i386
- What I'm interested in though is to cross-compile for Debian on
- beaglebone black, beagleboard xM, and raspberry pi.
- For OpenWRT it seems straightforward since it already comes with a
- toolchain and build system.
- I'd like to also sort out how to build multiple rust compilers, one
- for each architecture.
- [1] https://launchpad.net/gcc-arm-embedded/+download
- Entry: arm-linux-gnueabi-*-4.7
- Date: Fri Sep 12 22:09:25 CEST 2014
- Packages from emdebian all have a -4.7 version postfix which isn't
- always supported in build systems looking for cross tools, e.g. rust.
- Use this to create symlinks:
- cd /usr/bin
- for i in arm*4.7; do ln -s $i $(basename $i -4.7); done
- Entry: Cortex M4F float vs fixed
- Date: Sun Sep 21 13:51:05 CEST 2014
- Float in M4F is VFP with missing features like double FP.
- FPv4-SP extension
- VFP float ops happen in S registers.
- VLDR/VSTR loads into / stores from S registers.
- Entry: Assembly remarks
- Date: Thu Sep 25 16:44:24 CEST 2014
- pc-relative addressing in arm is quite strange..
- 0xa (10) -> 40
- 0xb (11) -> 44
- but why is this not 40,42,44,46 ?
- looks like PC only increments every 2 instructions in thumb mode.
- 10002: 4b0a ldr r3, [pc, #40] ; (1002c <xpatch_init+0x2c>)
- 10004: 4a0a ldr r2, [pc, #40] ; (10030 <xpatch_init+0x30>)
- 10006: 4e0b ldr r6, [pc, #44] ; (10034 <xpatch_init+0x34>)
- 10008: 4d0b ldr r5, [pc, #44] ; (10038 <xpatch_init+0x38>)
- what is the point of __memset_veneer trampoline?
- what is the ip register?
- -> r12, scratch register / new-sb in inter-link-unit calls
- 00010520 <__memset_veneer>:
- 10520: b401 push {r0}
- 10522: 4802 ldr r0, [pc, #8] ; (1052c <__memset_veneer+0xc>)
- 10524: 4684 mov ip, r0
- 10526: bc01 pop {r0}
- 10528: 4760 bx ip
- 1052a: bf00 nop
- 1052c: 08014471 .word 0x08014471
- what's the difference between
- push {rx, ...}
- and
- stmdb sp!, {rx, ...}
- -> push/pop are aliases
- what are the d registers?
- 1007a: ed2d 8b0c vpush {d8-d13}
- -> floating point extension registers. i'm guessing this is just the
- s registers aliased as d (double) registers so the above is the
- same as:
- vpush {s16-s26}
- apparently, 2-word instructions do not need to be 2-word aligned.
- why is "ite ne" followed by movne?
- 100ce: 2b00 cmp r3, #0
- 100d0: bf14 ite ne
- 100d2: 4663 movne r3, ip
- 100d4: 463b moveq r3, r7
- again for "it mi", "submi"
- 10104: bf48 it mi
- 10106: 3a01 submi r2, #1
- -> conditional instructions must be inside an it block
- -> suffix condition or inverse
- -> up to 4 following instr conditional
- it seems gcc does insert vfma instructions (fused mul acc)
- Entry: measure optimality
- Date: Thu Sep 25 17:19:01 CEST 2014
- by computing the ratio of moves to math instructions
- Entry: neon vs. vfp
- Date: Fri Sep 26 17:52:30 CEST 2014
- Entry: Q or GE
- Date: Sat Sep 27 15:54:56 CEST 2014
- Point of Q: perform a series of operations, then check if overflow
- occured at the end.
- CPSR has the following 32 bits.[43]
- M (bits 0–4) is the processor mode bits.
- T (bit 5) is the Thumb state bit.
- F (bit 6) is the FIQ disable bit.
- I (bit 7) is the IRQ disable bit.
- A (bit 8) is the imprecise data abort disable bit.
- E (bit 9) is the data endianness bit.
- IT (bits 10–15 and 25–26) is the if-then state bits.
- GE (bits 16–19) is the greater-than-or-equal-to bits.
- DNM (bits 20–23) is the do not modify bits.
- J (bit 24) is the Java state bit.
- Q (bit 27) is the sticky overflow bit.
- V (bit 28) is the overflow bit.
- C (bit 29) is the carry/borrow/extend bit.
- Z (bit 30) is the zero bit.
- N (bit 31) is the negative/less than bit.
- [1] http://en.wikipedia.org/wiki/ARM_architecture
- [2] http://stackoverflow.com/questions/19557338/importance-of-qsaturation-flag-in-arm
- Entry: STM32F103 board
- Date: Wed Oct 29 14:20:54 EDT 2014
- Board info at [2].
- [master] [email protected]:~/armdev/stm32f103$ cat openocd.cfg
- set CHIPNAME stm32f103c8t6
- source [find interface/arm-usb-ocd.cfg]
- source [find target/stm32f1x.cfg]
- [master] [email protected]:~/armdev/stm32f103$ cat openocd
- #!/bin/bash
- cd $(dirname $0)
- exec openocd -f openocd.cfg "[email protected]"
- [master] [email protected]:~/armdev/stm32f103$ ./openocd
- Open On-Chip Debugger 0.8.0-dev-00173-gc98856b-dirty (2013-09-15-10:22)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.sourceforge.net/doc/doxygen/bugs.html
- Info : only one transport option; autoselect 'jtag'
- adapter speed: 1000 kHz
- adapter_nsrst_delay: 100
- jtag_ntrst_delay: 100
- cortex_m reset_config sysresetreq
- Info : clock speed 1000 kHz
- Info : JTAG tap: stm32f103c8t6.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
- Info : JTAG tap: stm32f103c8t6.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
- Info : stm32f103c8t6.cpu: hardware has 6 breakpoints, 4 watchpoints
- Error: stm32f103c8t6.cpu -- clearing lockup after double fault
- Polling target stm32f103c8t6.cpu failed, GDB will be halted. Polling again in 100ms
- Polling target stm32f103c8t6.cpu succeeded again
- C-c C-c
- TODO: compile latest openocd.
- [1] http://electronics.stackexchange.com/questions/30688/clearing-lockup-after-double-fault
- [2] http://www.chinalctech.com/index.php?_m=mod_product&_a=view&p_id=1029
- Entry: libopencm3
- Date: Wed Oct 29 14:47:13 EDT 2014
- git clone git://github.com/libopencm3/libopencm3.git
- cd libopencm3
- make
- This will yield lib/*.a including:
- lib/libopencm3_stm32f1.a
- git clone https://github.com/libopencm3/libopencm3-examples.git
- cd examples/stm32/f1/other/usb_cdcacm
- make OPENCM3_DIR=/home/tom/git/libopencm3
- [master] [email protected]:~/git/libopencm3-examples/examples/stm32/f1/other/usb_cdcacm$ ~/armdev/stm32f103/gdb cdcacm.elf
- GNU gdb (GDB) 7.6.1
- ...
- Reading symbols from /home/tom/pub/git/libopencm3-examples/examples/stm32/f1/other/usb_cdcacm/cdcacm.elf...done.
- 0xffffffff in ?? ()
- (gdb) load
- Loading section .text, size 0x1528 lma 0x8000000
- Loading section .data, size 0x14 lma 0x8001528
- Start address 0x80011a0, load size 5436
- Transfer rate: 9 KB/sec, 2718 bytes/write.
- Entry: Openocd 0.8.0
- Date: Wed Oct 29 15:42:54 EDT 2014
- Let's start with latest release
- wget http://superb-dca3.dl.sourceforge.net/project/openocd/openocd/0.8.0/openocd-0.8.0.tar.gz
- cd openocd-0.8.0/
- ./configure \
- --enable-maintainer-mode \
- --enable-legacy-ft2232_libftdi \
- --enable-ftdi \
- --enable-ti-icdi \
- --enable-jlink
- ft2232 for olimex ARM-USB-OCD
- Entry: ftdi driver to replace ft2232 driver for olimex ARM-USB-OCD
- Date: Wed Oct 29 15:55:21 EDT 2014
- ft2232 driver is deprecated. Compiling it anyway doesn't work for the
- olimex-arm-usb-ocd.cfg that's in openocd 0.8.0
- Ok, both configs are still present. Just prefix directory with 'ftdi'
- source [find interface/ftdi/olimex-arm-usb-ocd.cfg]
- Entry: Can't connect after flashing bad code + FIX
- Date: Wed Oct 29 17:16:31 EDT 2014
- Now I get:
- [master] [email protected]:~/armdev/stm32f103$ ./openocd
- Open On-Chip Debugger 0.8.0 (2014-10-29-15:46)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.sourceforge.net/doc/doxygen/bugs.html
- Info : only one transport option; autoselect 'jtag'
- adapter speed: 1000 kHz
- adapter_nsrst_delay: 100
- jtag_ntrst_delay: 100
- cortex_m reset_config sysresetreq
- Info : clock speed 1000 kHz
- Error: JTAG scan chain interrogation failed: all ones
- Error: Check JTAG interface, timings, target power, etc.
- Error: Trying to use configured scan chain anyway...
- Error: stm32f103c8t6.cpu: IR capture error; saw 0x0f not 0x01
- Warn : Bypassing JTAG setup events due to errors
- Warn : Invalid ACK 0x7 in JTAG-DP transaction
- When holding reset it does come up properly.
- [master] [email protected]:~/pub/git/armdev/stm32f103$ ./openocd
- Open On-Chip Debugger 0.5.0 (2011-08-09-08:45)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.berlios.de/doc/doxygen/bugs.html
- Info : only one transport option; autoselect 'jtag'
- 1000 kHz
- adapter_nsrst_delay: 100
- jtag_ntrst_delay: 100
- cortex_m3 reset_config sysresetreq
- 100 kHz
- Info : clock speed 100 kHz
- Info : JTAG tap: stm32f103c8t6.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
- Info : JTAG tap: stm32f103c8t6.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
- Info : stm32f103c8t6.cpu: hardware has 6 breakpoints, 4 watchpoints
- When releasing reset:
- Warn : Invalid ACK 0x7 in JTAG-DP transaction
- Polling target stm32f103c8t6.cpu failed, GDB will be halted. Polling again in 100ms
- When pressing reset:
- Polling target stm32f103c8t6.cpu succeeded again
- This started happening after uploading something.
- Keeping the reset button pressed:
- (gdb) connect
- Polling target stm32f103c8t6.cpu succeeded again
- Info : accepting 'gdb' connection from 3333
- Info : device id = 0x20036410
- Warn : STM32 flash size failed, probe inaccurate - assuming 128k flash
- Info : flash size = 128kbytes
- undefined debug reason 7 - target needs reset
- (gdb) mon reset
- Info : JTAG tap: stm32f103c8t6.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
- Info : JTAG tap: stm32f103c8t6.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
- So this worked:
- - physically hold target in reset
- - start openocd
- - start gdb (possibly with .elf)
- - issue "mon halt" then release physical reset
- => target is halted and can be programmed.
- I just erased the flash[1] and now it connects properly.
- (gdb) mon flash erase_address 0x08000000 0x00020000
- erased address 0x08000000 (length 131072) in 0.026083s (4907.411 KiB/s)
- Tried again - didn't work.
- With BOOT0=1 and BOOT1=1
- (gdb) mon flash banks
- #0 : stm32f103c8t6.flash (stm32f1x) at 0x08000000, size 0x00010000, buswidth 0, chipwidth 0
- (gdb) mon flash erase_address 0x08000000 0x00010000
- erased address 0x08000000 (length 65536) in 0.024643s (2597.086 KiB/s)
- [1] http://openocd.sourceforge.net/doc/html/Flash-Commands.html
- Entry: ACM demo
- Date: Wed Oct 29 17:37:58 EDT 2014
- Looks like it actually ran ok:
- Oct 29 16:46:54 zoo kernel: [86274.953817] usb 1-1.1.1.4.4: new full-speed USB device number 90 using xhci_hcd
- Oct 29 16:46:54 zoo kernel: [86275.044193] usb 1-1.1.1.4.4: New USB device found, idVendor=0483, idProduct=5740
- Oct 29 16:46:54 zoo kernel: [86275.044196] usb 1-1.1.1.4.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
- Oct 29 16:46:54 zoo kernel: [86275.044197] usb 1-1.1.1.4.4: Product: CDC-ACM Demo
- Oct 29 16:46:54 zoo kernel: [86275.044198] usb 1-1.1.1.4.4: Manufacturer: Black Sphere Technologies
- Oct 29 16:46:54 zoo kernel: [86275.044199] usb 1-1.1.1.4.4: SerialNumber: DEMO
- Oct 29 16:46:54 zoo kernel: [86275.044352] usb 1-1.1.1.4.4: ep 0x83 - rounding interval to 1024 microframes, ep desc says 2040 microframes
- Oct 29 16:46:54 zoo kernel: [86275.045072] cdc_acm 1-1.1.1.4.4:1.0: ttyACM0: USB ACM device
- Oct 29 16:46:54 zoo mtp-probe: checking bus 1, device 90: "/sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1.1/1-1.1.1.4/1-1.1.1.4.4"
- Oct 29 16:46:54 zoo mtp-probe: bus: 1, device: 90 was not an MTP device
- Entry: BOOT0 BOOT1
- Date: Wed Oct 29 17:57:57 EDT 2014
- There are two jumpers on the board: BOOT0, BOOT1.
- Boot jumpers are originally closest to the large pin header. (assuming that's 0)
- Trying different
- 0x20000000 RAM
- 0x08000000 Flash (mapped to 0)
- [1] http://stackoverflow.com/questions/22351703/stm32f030-and-boot0-pin
- Entry: libopencm3 build
- Date: Thu Oct 30 18:31:12 EDT 2014
- [master] [email protected]:~/pub/git/libopencm3-examples/examples/stm32/f1/other/usb_cdcacm$ OPENCM3_DIR=/home/tom/git/libopencm3 make V=1
- Using /home/tom/git/libopencm3 path to library
- arm-none-eabi-gcc -Os -g -Wextra -Wshadow -Wimplicit-function-declaration -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes -fno-common -ffunction-sections -fdata-sections -MD -Wall -Wundef -I/home/tom/git/libopencm3/include -DSTM32F1 -mthumb -mcpu=cortex-m3 -msoft-float -mfix-cortex-m3-ldrd -o cdcacm.o -c cdcacm.c
- arm-none-eabi-gcc --static -nostartfiles -L/home/tom/git/libopencm3/lib -Tcdcacm.ld -Wl,-Map=cdcacm.map -Wl,--gc-sections -mthumb -mcpu=cortex-m3 -msoft-float -mfix-cortex-m3-ldrd cdcacm.o -lopencm3_stm32f1 -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group -o cdcacm.elf
- One option per line:
- CFLAGS:
- -Os
- -g
- -Wextra
- -Wshadow
- -Wimplicit-function-declaration
- -Wredundant-decls
- -Wmissing-prototypes
- -Wstrict-prototypes
- -fno-common
- -ffunction-sections
- -fdata-sections
- -MD
- -Wall
- -Wundef
- -I/home/tom/git/libopencm3/include
- -DSTM32F1
- -mthumb
- -mcpu=cortex-m3
- -msoft-float
- -mfix-cortex-m3-ldrd
- LDFLAGS
- --static
- -nostartfiles
- -L/home/tom/git/libopencm3/lib
- -Tcdcacm.ld
- -Wl,-Map=cdcacm.map
- -Wl,--gc-sections
- -mthumb
- -mcpu=cortex-m3
- -msoft-float
- -mfix-cortex-m3-ldrd
- -lopencm3_stm32f1
- -Wl,--start-group
- -lc
- -lgcc
- -lnosys
- -Wl,--end-group
- EDIT: The -m flags were missing on the linker line.
- Entry: stm32f usb libopencm3
- Date: Thu Oct 30 18:50:33 EDT 2014
- libopencm3/lib/usb/usb_f107.c
- stm32fx07_ep_write_packet
- stm32fx07_poll
- Running the cdc example code:
- libopencm3-examples/examples/stm32/f1/other/usb_cdcacm
- Why is it using otg_hs.h and not usb.h ?
- Entry: SW turned off
- Date: Thu Oct 30 19:13:06 EDT 2014
- this might be the culprit ;)
- AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
- Entry: Stepping on the f103
- Date: Thu Oct 30 19:23:45 EDT 2014
- So I'm able to step through the code.
- (gdb) p/x *0x8000000
- $4 = 0x20005000
- (gdb) p/x *0x8000004
- $5 = 0x8001299
- But setting $pc doesn't work.
- This does seem to reset properly:
- (gdb) mon reset halt
- JTAG tap: stm32f103c8t6.cpu tap/device found: 0x3ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x3)
- JTAG tap: stm32f103c8t6.bs tap/device found: 0x16410041 (mfg: 0x020, part: 0x6410, ver: 0x1)
- target state: halted
- target halted due to debug-request, current mode: Thread
- xPSR: 0x01000000 pc: 0x08001298 msp: 0x20005000
- Registers are out of sync. How to reload?
- stepi seems to solve that..
- sometimes..
- not much consistent behaviour.
- still buggy as hell this stuff...
- let's upgrade gdb as well..
- it also complains about no hw breakpoint resources available. restarting openocd helped.
- anyways, seems to be "mostly ok". gud is working as well with gdb-7.8.1
- Entry: cdcacm example
- Date: Thu Oct 30 19:58:05 EDT 2014
- the elf built from libopencm3-examples works
- mine doesn't
- Entry: jitter
- Date: Fri Oct 31 08:46:46 EDT 2014
- http://www.keil.com/forum/20318/how-to-reduce-interrupt-jitter/
- Entry: arm linux rootfs qemu
- Date: Sun Nov 2 22:41:22 EST 2014
- # tar xf rootfs.tar.gz
- # cp /usr/bin/qemu-arm-static usr/bin
- # chroot . /usr/bin/qemu-arm-static /bin/sh
- Entry: boot process vybrid
- Date: Sun Nov 2 23:01:11 EST 2014
- [1] https://linuxlink.timesys.com/docs/gsg/twr_vf600
- Entry: Interactive C
- Date: Wed Nov 5 13:52:29 EST 2014
- Modify linker script to load into ram? This is just a vagues idea..
- Let's stick to uploading images as it seems to be quite fast on the
- STM32F103.
- I'd like to figure out though why the reset isn't always working.
- Entry: gud emacs
- Date: Wed Nov 5 15:54:31 EST 2014
- On zoo it works fine: source window comes up. On tx for some reason
- it doesn't..
- Reading symbols from /home/tom/armdev/stm32f103/cdcacm.elf...done.
- stm32f103_poll (dev=0x20000014 <usbd_dev>) at ../../usb/usb_f103.c:299
- 299 ../../usb/usb_f103.c: No such file or directory.
- Ah it doesn't find the file.
- How to add absolute paths to libopencm3?
- I recompiled it from ~/armdev/libopencm3 and now it works
- Entry: Debugging USB
- Date: Thu Nov 6 12:22:28 EST 2014
- Halting the CPU causes USB timeouts. Currently I've only managed to
- run the CDCACM application by completely disconnecting the debugger.
- I see two ways to deal with this:
- - Give up on debugging USB in gdb
- - Run a GDB stub over USB while running in the background
- The question is really, what do I expect from a debugger tied to a
- running real-time system?
- Essentially I want to inspect memory and possibly execute some small
- code routines.
- Maybe best to just use the GDB serial protocol. This would provide a
- "console" through GDB, would avoid having to define an ad-hoc
- protocol, and allows extension of any other kind of RPC that might be
- useful.
- I wonder if a micro like STM32F103 can set its own breakpoints /
- watchpoints?
- EDIT: One thing I didn't think about is that the protocol is
- absolutely horrible :)
- I wonder if there's a translation layer that can be used.
- Entry: OpenOCD on/off
- Date: Thu Nov 6 15:31:46 EST 2014
- Let's first focus on reliably restarting with debugger attached.
- I have a USB hub with power switches. If I flip the switch, I want
- openocd to stop. If I power on the JTAG interface, I want openocd to
- start.
- EDIT: see armdev/bin:
- -rwxr-xr-x 1 tom tom 301 Nov 6 14:50 openocd-dispatch
- -rwxr-xr-x 1 tom tom 1704 Nov 6 15:23 udev-arm-usb-ocd.sh
- Entry: Cortex M3 gdb stub
- Date: Thu Nov 6 15:44:37 EST 2014
- Need to find something to start from.
- What I want is async debugging[4].
- [1] https://code.google.com/p/nativeclient/issues/detail?id=2911
- [2] https://gitorious.org/pmp-firmware-s-rockbox/ondabox/source/a42a56d8b00a92379399a648a2b4f25d9f069c72:gdb/arm-stub.c
- [3] http://www.embecosm.com/appnotes/ean4/embecosm-howto-rsp-server-ean4-issue-2.html
- [4] http://www.embecosm.com/appnotes/ean4/embecosm-howto-rsp-server-ean4-issue-2.html#sec_extended_async
- [5] https://www.youtube.com/channel/UCVPF4xiSILwfgo-VfjVohzQ
- Entry: libopencm3 USB IN >64 bytes
- Date: Thu Nov 6 23:22:51 EST 2014
- To make a large transfer, a callback is necessary.
- The cdcacm example doesn't have one:
- usbd_ep_setup(usbd_dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, cdcacm_data_rx_cb);
- usbd_ep_setup(usbd_dev, 0x82, USB_ENDPOINT_ATTR_BULK, 64, NULL);
- usbd_ep_setup(usbd_dev, 0x83, USB_ENDPOINT_ATTR_INTERRUPT, 16, NULL);
- For IN enpoints this gets called after transfer is complete.
- Suspending output is a bit more painful than suspending input. So the
- solution is to either throw memory at the problem: generate output in
- memory and have a simple state machine export it, possibly doing some
- postprocessing (like RSP escapes).
- Alternatively, use a task that can be suspended. Some alternatives:
- - RTOS tasks
- - main program + interrupt state machines
- - cooperative multitasking [1]
- [1] http://hsl.wz.cz/tasks.htm
- Entry: gdb "console"
- Date: Fri Nov 7 18:39:50 EST 2014
- Using gdb as a console to a real-time application.
- RSP protocol is polled from the main real-time loop.
- GDB sees consistent view in between updates of other state machines.
- Allow:
- - memory get/set
- - image loading
- - monitor commands
- - execution of expressions, e.g. "print toggle_pin(1)"
- However, there is no "current thread" in the sense of a halted target.
- $Pe=c9210008#b9
- +$#00
- +$G000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637c92100083c3d3e3f#f6
- +$#00
- +$G000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323330353637c92100083c3d3e3f#f2
- +$#00
- +$G000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323330353637c921000874020008#29
- +$#00
- +$Z0,80021c8,2#aa
- +$#00
- +$m80021c8,2#61
- +$0001#c1
- +$X80021c8,0:#84
- +$#00
- +$M80021c8,2:bebe#09
- +$#00
- +$vCont?#49
- +$#00
- +$Hc0#db
- +$#00
- +$c#63
- +$#00
- +
- That was in response to:
- (gdb) p main()
- warning: Invalid remote reply:
- This contains commands:
- G
- Z
- m
- X
- M
- vCont?
- H
- c
- What I want is maybe non-stop mode?
- Maybe it doesn't matter. There is no access to other threads anyway
- since there is no active contect while prodding at the console. Only
- state.
- So what is the current thread? Just a fake loop? The real main loop
- that polls the USB OUT endpoint?
- Entry: Look in gdb source for stubs
- Date: Fri Nov 7 21:24:19 EST 2014
- Seems old.. No ARM stub?
- The one from RockBox might actually be functional.
- I have some idea now how it works, so maybe keep that one intact?
- Entry: continue
- Date: Sat Nov 8 13:26:29 EST 2014
- So the basic structure of the stub seems to be working. Most of
- what's left is low-level fiddling: continue.
- GDB also complains:
- (gdb) p main()
- Program received signal SIGTRAP, Trace/breakpoint trap.
- 0xbc020008 in ?? ()
- The program being debugged was signaled while in a function called from GDB.
- GDB remains in the frame where the signal was received.
- To change this behavior use "set unwindonsignal on".
- Evaluation of the expression containing the function
- (main) will be abandoned.
- When the function is done executing, GDB will silently stop.
- Assuming this is because the stack pointer is not at the expected
- position. How to find out what it actually expects? The simplest way
- seems to just reuse working code from the RockBox stub.
- Entry: usbmon
- Date: Sun Nov 9 12:21:09 EST 2014
- zoo:/home/tom# mount -t debugfs none_debugs /sys/kernel/debug
- zoo:/home/tom# modprobe usbmon
- zoo:/home/tom# ls /sys/kernel/debug/usb/usbmon
- 0s 0u 1s 1t 1u 2s 2t 2u 3s 3t 3u 4s 4t 4u
- cat /sys/kernel/debug/usb/usbmon/0u |grep :1:026
- Note that [1] says:
- The length of collected data is limited and can be less than the
- data length reported in the Data Length word.
- I've seen this for packet lengths of 128 where only 8 words (32 bytes)
- are presented.
- [1] https://www.kernel.org/doc/Documentation/usb/usbmon.txt
- Entry: debugging USB on f103
- Date: Sun Nov 9 13:22:15 EST 2014
- So it seems that the low-level libopencm3 part is running fine. RSP
- stub is mostly working as well. There is no real need for debugging
- at the packet level.
- Something I noticed though is that the max packet size seems to be 32
- instead of 64. Strange..
- So, what I want to do is to make a pass-through for the RSP data that
- will log it. The simplest way to do this is to bridge /dev/ttyACM0 to
- a tcp port and use a tcp sniffer.
- socat /dev/ttyACM0 TCP-LISTEN:12345,reuseaddr
- tcpflow -i lo -C -e port 12345
- Entry: p main() hangs gdbstub
- Date: Sun Nov 9 13:37:15 EST 2014
- Reason:
- $X800211c,2:..#fb
- $X800211c,2:..#fb
- $X800211c,2:..#fb
- $X800211c,2:..#fb
- Might be because writing to flash causes an exception.
- EDIT: Sending Exx at least prevents the crash.
- It would be better to not use software breakpoints.
- I.e. let the stub provide a more abstract interface.
- Entry: fixing p main()
- Date: Sun Nov 9 14:18:19 EST 2014
- It tries to set a breakpoint:
- $m8002150,2#2b
- +$0023#c5
- +
- $X8002150,2:..#cc
- +$Efd#0f
- +
- Here 0x8002150 is the reset handler.
- Why does it pick that particular address?
- It doesn't seem to depend on the original $pc.
- The 'Z' packet is used for breakpoints. It tries this first:
- $Z0,8002154,2#78
- +$#00
- So let's implement it.
- Ok, done. No more writing software breakpoints.
- So why reset vector? Maybe it is totally arbitrary?
- Need to look at what it sets:
- $Pe=cd210008#e4
- +$OK#9a
- +
- $Pd=f8ffffff#f3
- +$OK#9a
- +
- $Pf=f0110008#b3
- +$OK#9a
- +
- $P19=00000001#78
- +$OK#9a
- +
- $Z0,80021cc,2#d5
- +$OK#9a
- +
- This corresponds to:
- lr 0x080021cd 134226381
- sp 0xfffffff8 0xfffffff8
- pc 0x080011f0 0x80011f0 <main>
- cpsr 0x01000000 16777216
- bp+1 == lr (lsb is thumb mode)
- It seems that the BP location really doesn't matter.
- It reserves 2 words on the current stack frame. Original sp = 0;
- What about cpsr?
- [1] https://sourceware.org/gdb/onlinedocs/gdb/Calling.html
- Entry: STM32F103C8T6
- Date: Sun Nov 9 20:11:08 EST 2014
- The board I'm using has an STM32F103C8T6:
- 20kB RAM 0x5000
- 64kB Flash
- $3.18 at future electronics[1].
- For debugging it might be good to have an STM32F1 chip with a little
- more RAM. Which one?
- Package names[2]:
- STM32F103 C|R|V|Z F|G
- Package:
- C = LQFP 48
- R = LQFP 64
- V = LQFP 100
- Z = LFBGA 144
- Flash / RAM kb:
- 6 = 32 / 10
- 8 = 64 / 20
- B = 128 / 20
- C = 256 / 48
- D = 384 / 64
- E = 512 / 64
- F = 758 / 96
- G = 1024 / 96
- What are the last 2 characters from the pin numbering? (T6)
- [1] http://www.futureelectronics.com/en/technologies/semiconductors/microcontrollers/32-bit/Pages/5227137-STM32F103C8T6.aspx?IM=0
- [2] http://www.st.com/web/catalog/mmc/FM141/SC1169/SS1031/LN1565
- Entry: gdbstub flash
- Date: Sun Nov 9 21:18:34 EST 2014
- GDB needs a memory map to handle flashing properly. However it might
- work with ordinary M packets as well.
- It attempts to write 192 bytes at a time:
- $X8000000,c0:...
- Refman 3.3.3:
- - The Flash memory can be programmed 16 bits (half words) at a time.
- - The Flash memory erase operation can be performed at page level
- Page size is
- - 1kB for medium density devices (< 128kb)
- - 2kB for high density
- So when making the erase explicit this can be supported using ordinary
- memory access.
- Anyways.. its probably not too hard to support it:
- - qSupported[2]
- - qXfer:memory-map:read::offset,length
- - vFlashErase:addr,length
- - vFlashWrite:addr:XX
- - vFlashDone
- [1] https://sourceware.org/gdb/onlinedocs/gdb/Memory-Map-Format.html#Memory-Map-Format
- [2] https://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html#qSupported
- Entry: stm32f103 and jtag
- Date: Mon Nov 10 01:56:26 EST 2014
- Can't get the USB to work while the JTAG is plugged in. Wondering
- what this is.. Maybe clock issue? Pins don't seem to conflict.
- Let's try with a SWD interface.
- Thing is though that this probably supports DFU. Together with serial
- monitor this might not need a separate JTAG adapter.
- Entry: Other arguments
- Date: Mon Nov 10 02:17:25 EST 2014
- (gdb) p $sp
- $9 = (void *) 0x20001000
- (gdb) p test_call(1,2,3,4,0x40,0x41,0x42,0x43)
- $X20000ff4,4:C...#27
- $X20000ff0,4:B...#22
- $X20000fec,4:A...#53
- $X20000fe8,4:@...#27
- It calls the code with sp 20000fe8
- $Pd=e80f0020#e6
- Entry: What are these other registers?
- Date: Mon Nov 10 02:22:40 EST 2014
- $P13=00000000f050510200000000#b4
- $P19=00000000#77
- Entry: 48kB image?
- Date: Tue Nov 11 12:35:35 EST 2014
- Image for gdbstub seems large. These are the hogs:
- 000002ee,__hexnan
- 000003ec,_realloc_r
- 00000530,_malloc_r
- 00000588,__gethex
- 00000eac,_strtod_r
- 000011b8,__ssvfscanf_r
- 000011f8,_dtoa_r
- 00001ada,_svfprintf_r
- I'm not sure why printf is in there, but scanf can probably be avoided
- as it's only parsing hex numbers.
- Entry: Weird stuff..
- Date: Tue Nov 11 21:29:10 EST 2014
- set *(uint32_t*)0x200000AC = ((uint32_t)counter_tick)|1
- Entry: freenode #stm32
- Date: Wed Nov 12 00:44:40 EST 2014
- Look for the following in the irc log [1].
- 00:42 < doelie> hi. anyone know if it's possible to set breakpoint registers from inside the machine as
- opposed to jtag/sw? i'm writing a special purpose gdb stub and was wondering if this even
- makes sense.
- 00:43 < doelie> particular machine is stm32f103c8
- dongs' replies lead to:
- Debug inspection and monitor control register DEMCR[2].
- FPB (flash patch breakpoint) programmer model[3].
- Flash Patch Remap Register[4].
- FP_CTRL 0xE0002000 See Flash Patch Control Register
- FP_REMAP 0xE0002004 See Flash Patch Remap Register
- FP_COMP0 0xE0002008 See Flash Patch Comparator Registers
- FP_COMP1 0xE000200C
- FP_COMP2 0xE0002010
- FP_COMP3 0xE0002014
- FP_COMP4 0xE0002018
- FP_COMP5 0xE000201C
- FP_COMP6 0xE0002020
- FP_COMP7 0xE0002024
- The STM32F103 reference manual doesn't mention it except for a brief
- blurb at 31.12
- [1] http://xob.kapsi.fi/~jpa/stm32/2014-11.log
- [2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/CEGHJDCF.html
- [3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/ch11s04s01.html
- [4] http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337e/ch11s04s01.html#BABGGDHH
- Entry: GDB Stub Developer’s Guide
- Date: Thu Nov 13 12:54:51 EST 2014
- http://www.kpitgnutools.com/developersguide.htm
- Entry: smstub vectors
- Date: Thu Nov 13 13:11:04 EST 2014
- How should vectors be handled?
- Should the stub stay out of the way here?
- Check VTOR register[1][2] 0xE000ED08
- In libopencm3.h all vectors are declared weak in libopencm3/stm32/f1/nvic.h
- [1] http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/Ciheijba.html
- [2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/CIHFDJCA.html
- Entry: Stub mainloop
- Date: Thu Nov 13 13:37:34 EST 2014
- Leave it up to the application. Poll GDB from its main loop? No that
- would complicate things.
- Entry: stm32f peripheral info using libopencm3
- Date: Sat Nov 15 11:23:39 EST 2014
- Starting from example [1].
- rcc_peripheral_enable_clock
- timer_reset
- timer_set_mode
- Current timer value can be read out at:
- TIM1_CNT
- [1] https://gitorious.org/mdr32f9-libopencm3/mdr32f9-libopencm3-examples/source/f5b0aa5638b9903c7b76d14786d8090926cf7bb9:examples/stm32/f1/stm32-h103/timer/timer.c
- Entry: stm32f startup
- Date: Sat Nov 15 12:41:01 EST 2014
- So reading out the TMR6 registers at 0x40001000 gives all 0.
- Something isn't starting up properly.
- Entry: Debug remote protocol
- Date: Sat Nov 15 12:53:58 EST 2014
- It can be enabled in gdb as well:
- (gdb) set debug remote 1
- Entry: Larger stm32f103 board works
- Date: Sat Nov 15 12:58:29 EST 2014
- Clock issue:
- - rcc_clock_setup_in_hsi_out_48mhz(); // internal
- + rcc_clock_setup_in_hse_8mhz_out_72mhz();
- Entry: I need a flat register map
- Date: Sat Nov 15 13:01:39 EST 2014
- How to generate from libopenocd defs?
- Tried to mine the header files, but that was a half-working mess of
- ad-hoc shell scripts. Now using structs with instances defined in
- special secions + linker script. Can probably be automated further.
- (gdb) p/x M40.RCC.APB1ENR
- 0x800000
- That's just USB.
- TIM6 is not running
- It just refuses to set that bit:
- (gdb) set M40.RCC.APB1ENR = 0x800010
- (gdb) p/x M40.RCC.APB1ENR
- $78 = 0x800000
- Setting TIM2 does work.
- (gdb) set M40.RCC.APB1ENR = 0x800001
- (gdb) p/x M40.RCC.APB1ENR
- $81 = 0x800001
- Maybe the device just doesn't have a TIM5,TIM6?
- Yes, that's why it doesn't work!
- The 103x8 devices only have 4 timers 1,2,3,4
- I have 103C8 and 103R8
- Entry: de-jitter
- Date: Sat Nov 15 23:57:26 EST 2014
- Seems that interrupt latency is 12 cycles.
- Check this again[1] to see the special cases.
- If there are exceptions due to bus operation, de-jittering can be done
- based on timer values followed by a jump into a nop sequence.
- It's a bit harder to understand than on a PIC :)
- [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16366.html
- Entry: TIM2
- Date: Sun Nov 16 00:07:47 EST 2014
- So can pull one of the several interrupt flags in DEV.TIM2.SR
- Figure out how this gets routed to the ISR.
- Entry: Stub and vectors
- Date: Tue Nov 25 09:22:57 EST 2014
- Move vector table.
- (gdb) p/x (int)&vector_table
- $2 = 0x8002800
- Check VTOR register[1][2] 0xE000ED08
- OK works
- #include <libopencm3/cm3/scb.h>
- /* Set Vector Table Offset to our memory based vector table */
- SCB_VTOR = (uint32_t)&vector_table;
- Entry: registers and linker
- Date: Tue Nov 25 09:50:15 EST 2014
- Problem with using linker for register structs is that it will not
- optimize the indirection. I.e. base of struct is patched.
- DEV.TIM2.SR
- This loads &DEV as 0x40000000, then adds offset of TIM2.SR
- Maybe linker can't patch addresses as offsets, i.e. patching a word by
- adding to it?
- Entry: F1 USART receive
- Date: Thu Dec 18 13:55:49 EST 2014
- CR1[RE] = 1
- It seems that SR needs to be read for DR to be updated.
- Entry: Setting bits
- Date: Sat Feb 7 11:43:48 EST 2015
- What is the fastest way to set a bit in a register on CM3?
- Compiler generates:
- ldr r3, [pc, #32] ; r3 <- 0x40000010 TIM2.SR
- ldr r2, [r3, #0]
- bic.w r2, r2, #1
- str r2, [r3, #0]
- The equivalent in gas is:
- .thumb
- .syntax unified
- tim2_isr:
- ldr r3, tim2_reg
- ldr r2, [r3, #0]
- bic r2, r2, #1
- bx lr
- .align
- tim2_reg:
- .word 0x40000010
- Unified syntax[1].
- .syntax [unified | divided]
- This directive sets the Instruction Set Syntax as described in the ARM-Instruction-Set section.
- W suffix forces a 32-bit instruction encoding. The .N suffix forces a 16-bit instruction encoding.
- [1] https://sourceware.org/binutils/docs-2.23/as/ARM_002dInstruction_002dSet.html#ARM_002dInstruction_002dSet
- Entry: Bit-banded accesses versus read-modify-write accesses
- Date: Sat Feb 7 13:17:24 EST 2015
- The bit-band operation to achieve the same result requires only a
- single instruction and one or two processor clock cycles.
- These operations are available in a fixed range of addresses, with
- each bit in the address range 0x20000000 to 0x200fffff being aliased
- at a word (4-byte) aligned address in the range 0x22000000 to
- 0x23fffffc in the SRAM space. The same mechanism applies to the
- corresponding address ranges in the region 0x40000000 to 0x43fffffc in
- the Peripheral space.
- This setting TIM2.SR.UIF = 0 on STM32F103
- 8002e52: 4b08 ldr r3, [pc, #32] ; (8002e74 <tim2_isr+0x24>)
- 8002e54: 2200 movs r2, #0
- 8002e56: 601a str r2, [r3, #0]
- ...
- 8002e74: 42000400 .word 0x42000400
- [1] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16401.html
- [2] http://spin.atomicobject.com/2013/02/08/bit-banding/
- Entry: rust
- Date: Mon Feb 16 02:05:31 EST 2015
- Compile from recent git.
- See bin/rustc* and rust/Makefile
- Qemu works with transparent user mode emulation if qemu-user is
- installed (probably needs armel arch?).
- Entry: STM32F level triggered interrupts
- Date: Sat May 9 02:00:30 CEST 2015
- EXTI is all edge triggered. This is bad for some applications when it
- is possible to miss an edge during setup.
- The basic problem is that it is possible that an event arrives right
- before a clear pending operation.
- It seems possible to work around this by performing some extra reads..
- [1] https://electronics.stackexchange.com/questions/158749/how-to-use-level-triggered-interrupts-with-stm32f1xx?rq=1
- Entry: Qemu binfmt
- Date: Sat Jun 27 12:18:50 EDT 2015
- The "binfmt" how did it work again?
- qemu-user-binfmt
- Entry: multiarch cross-compile
- Date: Sat Jun 27 12:58:36 EDT 2015
- On zoo there is a dev32 lxc. Start there.
- Entry: semaphores
- Date: Sat Jul 18 03:48:42 EDT 2015
- http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s03s03.html
- Entry: fakeroot + qemu-arm-static
- Date: Mon Aug 31 14:18:08 CEST 2015
- [1] https://lists.debian.org/debian-embedded/2011/04/msg00001.html
- Entry: rust bare metal arm
- Date: Sun Sep 20 07:08:42 EDT 2015
- http://antoinealb.net/programming/2015/05/01/rust-on-arm-microcontroller.html
- Entry: qemu-arm-static
- Date: Fri Mar 25 18:39:49 EDT 2016
- Hard to understand how it actually works, but with binfmt-support, it
- seems to be sufficient to place the target ld, ld-linux and libc in
- /etc/qemu-binfmt/arm/lib
- [email protected]:/etc/qemu-binfmt/arm/lib# ls -l
- total 1344
- -rwxr-xr-x 1 root root 134328 Feb 27 00:48 ld-2.18.so
- lrwxrwxrwx 1 root root 10 Feb 22 23:03 ld-linux.so.3 -> ld-2.18.so
- -rwxr-xr-x 1 root root 1239048 Feb 27 00:48 libc-2.18.so
- lrwxrwxrwx 1 root root 12 Feb 22 23:02 libc.so.6 -> libc-2.18.so
- https://lists.debian.org/debian-embedded/2011/04/msg00001.html
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=604268;msg=70
- https://wiki.debian.org/QemuUserEmulation
- So the way to go seems to be to get binfmt-support to work properly.
- That is then linked to run qemu-arm-static (or any other program).
- qemu-arm-static uses /etc/qemu-binfmt/arm/lib (hardcoded default).
- So i have it working up to the point that it works manually:
- cd $ROOT/bin ; qemu-arm-static ls
- but not automatically
- Installing qemu-user-binfmt made it work on zoo, which uses qemu-arm from qemu-user package.
- Also works on zoe, but I need to keep /etc/qemu-binfmt/arm/lib directory.
- I still find it odd that I can't chroot..
- Ha, on zoo I had trouble before it looks like:
- [email protected]:/lib$ ls -al ld-linux.so.3
- lrwxrwxrwx 1 root root 28 Feb 17 17:26 ld-linux.so.3 -> arm-linux-gnueabi/ld-2.21.so
- It's part of libc6:armel
- Final word:
- dpkg --add-architecture armel
- apt-get update
- apt-get install libc6:armel qemu-user-binfmt
- or
- apt-get install libc6:armel qemu-user-static
- Both work.
- Now why doesn't the timesys chroot work?
- Wow this is tricky... This worked:
- chroot mnt qemu-arm-static -L / bin/sh
- This runs qemu-arm-static inside chroot, which is then told to look
- for libraries at / instead of its default location.
- Entry: openocd stlink
- Date: Tue Mar 28 11:19:21 EDT 2017
- really... fucking dev tools. can't figure out how to halt the
- processor. it comes up fine but won't go into halt.
- Open On-Chip Debugger 0.9.0 (2015-05-28-17:08)
- Licensed under GNU GPL v2
- For bug reports, read
- http://openocd.org/doc/doxygen/bugs.html
- Info : auto-selecting first available session transport "hla_swd". To override use 'transport select <transport>'.
- Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
- adapter speed: 1000 kHz
- adapter_nsrst_delay: 100
- none separate
- Info : Unable to match requested speed 1000 kHz, using 950 kHz
- Info : Unable to match requested speed 1000 kHz, using 950 kHz
- Info : clock speed 950 kHz
- Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748
- Info : using stlink api v2
- Info : Target voltage: 3.177706
- Info : stm32f103c8t6.cpu: hardware has 6 breakpoints, 4 watchpoints
- Info : accepting 'gdb' connection on tcp/3333
- Info : device id = 0x20036410
- Warn : STM32 flash size failed, probe inaccurate - assuming 128k flash
- Info : flash size = 128kbytes
- undefined debug reason 7 - target needs reset
- Tried on HY-MiniSTM32V, separately powered. Now "mon halt" worked:
- 1. power up board.
- 2. power up programmer
- 3. target remote
- 4. monitor halt
- Then
- 5. reset board
- 6. monitor halt
- target state: halted
- target halted due to debug-request, current mode: Thread
- xPSR: 0x61000000 pc: 0x08000288 msp: 0x20001ff0
- Now trying fresh small strip board, stlink-powered. That worked.
- Looks like my board is bad. Taking it out of the breadboard.
- Entry: git-private/armdev
- Date: Thu Apr 20 10:13:07 EDT 2017
- Does it need to be private? IIRC that was just a lazy thing because
- at some point it contained some NDA stuff. It might be enough to just
- kill the history?
- It contains build tools setup and minimal libc for a host of arm and
- other targets, including qemu. Also has rust for arm setup.
- It seems simplest to leave it as is, and move relevant code to
- git/uc_tools
- The arm.txt file doesn't seem to contain NDA stuff so moved it to
- papers/arm.txt where you're reading it now.
- Entry: uc_tools bootloader + rust code?
- Date: Sat Sep 15 10:18:42 EDT 2018
- What is needed to load a piece of rust code onto the STM32 boot
- loader? Say I want to write the serial port handler.
- So it needs to be able to:
- - go at a phsical address and find a structure there
- - set the function points to point into rust code
- The first is simple, the rest I don't know how to do.
- How can C code call a Rust function?
- https://users.rust-lang.org/t/how-to-call-rust-library-in-c/11436
- #[no_mangle]
- extern "C" fn foo() {
- // stuff
- }
- http://greyblake.com/blog/2017/08/10/exposing-rust-library-to-c/
- Maybe the simplest way is to create a static library.
- https://doc.rust-lang.org/cargo/reference/manifest.html#building-dynamic-or-static-libraries
- Practically, start with git/armboot, and produce an .a library
- exposing read and write functions. Then write a small C wrapper to
- glue it together.
- It's not git/armboot. This is old code.
- Entry: system level emulation
- Date: Tue May 28 10:41:20 EDT 2019
- Using binfmt it is possible to have qemu run at the linux system call
- interface, i.e. only the application binary is emulated.
- How to use a debugger with that?
- E.g.:
- [email protected]:~/exo/axbc_overlay/mk/build$ qemu-arm-static ./test.pi.elf
- Entry: fractional multiplication in C
- Date: Sun May 17 19:13:30 EDT 2020
- Probably best to do it in asse
Recent Pastes