You can search these dumps for addresses that appear in the romlog, which will help you find the corresponding C source. Note that Thumb addresses may appear in the stack dump or registers with the lowest bit set.

You can search these dumps for addresses that appear in the romlog, which will help you find the corresponding C source. Note that Thumb addresses may appear in the stack dump or registers with the lowest bit set.

−

Note: The [[CHDK-Shell]] tool may automatically delete these files after building by default. Disable "Compile Options > Skip GMAKE clean AFTER compilation" to keep them. [Note from author: CHDK-Shell will also save dumps to /bin/logs/dump-{cameraname}-{firmware}.txt '''by default'''. This is controlled by the checkbox named "ELF objdump", just above the "Compile Selected" button ]

+

The [[CHDK-Shell]] tool will save dumps to bin/logs/dump-{cameraname}-{firmware}.txt '''by default'''. This is controlled by the checkbox named "ELF objdump", just above the "Compile Selected" button. You can also disable"Compile Options > Skip GMAKE clean AFTER compilation" to keep them in the original location.

==Memory values==

==Memory values==

Revision as of 03:25, January 7, 2013

Contents

Intruduction

This page collects tools and techniques for debugging CHDK code

LEDs

A simple way to see if a particular code path is reached.

In a complete CHDK port the started() and finished() macros turn on and off the CHDK debug LED . The debug LED is normally the blue direct print LED. On cameras that do not have a direct print LED, a different one will be used. The AF led should NOT be set as the debug LED in any build intended for normal use, because it would interfere with taking pictures.

Using LEDs directly

First, you need to know an LED MMIO address.

TODO link some led finder code.

The LED is turned on by writing 0x46 to the address, and turned off by writing 0x44

C

From C, you can do something like this to blink an LED cnt times. The nops are used to create a delay. The length of the delay will depend on the camera and whether caches are currently enabled, but should be sufficient to see the led blinking.

If you call this code from inline assembler, you need to make sure to preserve any registers. The ASM_SAFE macro may be used for this purpose.

In some parts of the code, the stack may not be properly set up, in which case any variables should be static or global.

If you want to put this code in an __attribute__((naked)) function, you should also avoid using local variables. In general you should not put any C code in these functions.

In some parts of the code - especially early in the booting process - the use of delay loops to actually blink the camera LED can potentially disrupt the boot timing. It is safer to simply turn on the LED rather than blink it.

Using LEDs from Canon Basic/Eventprocs

Camera crash logs (romlog)

When the canon firmware crashes, it will normally write the current registers, a stack dump, and the recent entries from the camera log to internal flash memory and then shut down. This is generally referred to as the romlog.

Reading the romlog

As of changeset 1432, the romlog can be saved from the CHDK menu, using "miscellaneous stuff->Debug Parameters->Save ROM crash log"

Some older vxworks cameras will automatically shut down after saving the log. This is normal.

If the camera has never crashed, the romlog function will fail.

Interpreting the romlog

Text below refers the the plain text romlogs produced by DryOS and some later vxworks cameras. Older vxworks cameras output the romlog in a binary format, some information is available in this forum thread http://chdk.setepontos.com/index.php?topic=5394.0

The first line of the romlog describes the kind of error that occurred. Known errors include ASSERT, EXCEPTION, WATCHDOG and HARDWARE DEFECT. ASSERT and EXCEPTION are most commonly encountered in CHDK development. The remainder of the log varies slightly depending on the error.

The stack dump can help you figure out which functions were called an in some cases what their parameters were. Rather than actually working through all the calls, it is frequently sufficient to just look for addresses that look like code, either ROM or within CHDK address space. Keep in mind that the final entry in the stack dump is the call to assert itself.

Unlike assert, the exception log includes the CPU registers at the time the exception occurred. The 15th register is LR, 16th register is the instruction pointer (PC), and the 17th is the program status word.

Keep in mind the LR will point to the instruction after the BL instruction, and may have lowest bit set if the call was from thumb code. PC will not have the low bit set in thumb code.

Note the above appears to be triggered by CHDK in this case, not an actual hardware defect. thread

Common Exception Vectors

In CHKD debugging, the most commonly encountered exception is 0x10 Data abort. This occurs when the code attempts to access an invalid memory address. 0x4 Undefined Instruction is also is also common, caused by bad code pointers or stack corruption.

Locating CHDK code from romlog addresses

The CHDK build process writes disassembly dumps of the main CHDK binary. The dump for the main code is stored in core/main.dump

The dump for the loader code (which includes the main code, but not located at the final address) is stored in loader/<camera>/main.dump

You can search these dumps for addresses that appear in the romlog, which will help you find the corresponding C source. Note that Thumb addresses may appear in the stack dump or registers with the lowest bit set.

The CHDK-Shell tool will save dumps to bin/logs/dump-{cameraname}-{firmware}.txt by default. This is controlled by the checkbox named "ELF objdump", just above the "Compile Selected" button. You can also disable "Compile Options > Skip GMAKE clean AFTER compilation" to keep them in the original location.

Memory values

There are two common ways to inspect memory values in CHDK

Misc debug values

This displays four memory values in the CHDK OSD. The display can be turned on or of in the CHDK menu under miscellaneous stuff->Debug parameters->Show misc. values

By default, the values listed below are shown, but this can be be changed in core/gui.c gui_draw_debug_vals_osd()

u: usb power state
1: the address selected in the memory browser (see below)
f: the focus_busy value
z: the zoom_busy value

Early in the porting process, you may want to hard code this to always be displayed, and also uncomment the first call to gui_draw_debug_vals_osd() in gui_draw_osd to ensure it is drawn even if some variables are wrong.

Memory browser

This allows you to interactively view memory addresses. The right/left buttons increment/decrement the address, and the zoom in/zoom out controls the increment size. On cameras without zoom button or zoom lever, the Disp button can be used to change the increment size.

Note that if you attempt to browse an invalid memory location (or the selected memory location holds an invalid address), the camera will shut down with an exception.

By default, the value of the selected address is also shown in misc debug values, so you can use this to set a "watch" without changing code.

Logging camera console output

Many firmware functions output information to the cameras console. Normally, this is discarded, but it it can be recorded with the following methods.

Some functions that put useful information to the camera console

ShowCameraLog outputs recent entries in the cameras log. (to be described more below!)

Printf can be used to send arbitrary text to the camera console (UART).

LogPrintf (not an event proc, need to find the address) can send output to the camera log. LogPrintf takes a number as the first argument, followed by a format string and a variable number of additional arguments. The number specifies a prefix that appears on the log message, either SS: or UI:, and may also have other functions. 0x120 is generally used for SS. The camera log does not appear in the camera standard output by default, but recent entries can be sent there using the ShowCameraLog event proc. Recent log entries will also appear in ROMLOGs.

UART redirection (DryOS)

DryOS (TODO and possibly late vxworks ?) cameras can redirect UART console output with StartRedirectUART Event Procedure. To use this function, a file named uartr.req must be present in the root of the SD card, and must start with the bytes 0x77 0x21 0xce 0x82 .

StartRedirectUART(int buffer_size,const char *filename)

buffer_size controls how much output is buffered. The value is rounded up to 8192 bytes.

filename is the name of the file to write. If NULL, an name will be automatically picked based on tick count. If a name is given, output will be appended to the file.

The standard CHDK distribution includes the uartr.lua lua module which provides an interface to this.

Note that a sleep() appears to be required between enabling uart redirection and the first output being recorded.