Saturday, March 25, 2017

One-part AVR-controlled "boost converter"

I built a crappy AVR-controlled boost converter with just one part (an inductor) that can blink a blue LED when you power it at 2.3 V. See the video here:

I did this because there was a challenge on a cool electronics blog that I follow.

The "boost converter" is pretty crappy because it does not produce a stedy voltage and it is only useful when the input voltage is between 2.3 V and 2.5 V. Below that, my AVR ATmega328P seems to stop running. Above that, the blue LED is on all the time (though it does get noticeably brighter when I run the boost).

In this system, VCC is only boosted by about 0.7 V; it can go a little bit higher if I use more I/O lines, but it can't go much higher than that because of the blue LED. If I take the blue LED away, I see shorter but more extreme boosts on VCC. With one I/O line, I see a boost of 1.2 V. With two I/O lines, I see a boost of 1.7 V, and it seems like the sudden boost causes issues for the AVR and it usually resets after one or two boosts. With three I/O lines, I see a very sharp boost of 2.0 V for 2 us, and it consistently causes the AVR to reset.

Update: I received a shirt from Josh for winning the contest. I like it!

The shirt is gray, has a picture of an inductor, and says: Winner! Josh.com Boost Converter Design Contest

Friday, October 21, 2016

GitHub.com hosts file

GitHub and other popular sites are suffering from a DDoS attack right now. In case you actually want to use GitHub, here are entries you can add to your system's hosts file:

192.30.253.113 github.com
103.245.222.133 assets-cdn.github.com

Just remember to remove these entries later once GitHub starts working again, since those IP addresses might change in the future without notice.

Wednesday, June 22, 2016

Detailed teardown of a Roomba Model 550 robot

I recently bought a Roomba for $5 from my neighbor at a garage sale. I tore it down in order to see what is going on inside it and learned a lot from it. Check out my detailed photo album on imgur.

Wednesday, February 24, 2016

Windows 32-bit structured exception handling example for GCC

I recently spent a few hours learning about structured exception handling (SEH) in 32-bit (i686) Microsoft Windows. The canonical article documenting this seems to be A Crash Course on the Depths of Win32™ Structured Exception Handling by Matt Pietrek in 1997.

After reading the first 1600 words of the article, I came across a code sample (Figure 3) that shows the most basic way one can use structured exception handling. The code uses C++ and a little bit of inline assembly to add its own exception handler to the beginning of the linked list of exception handlers that is stored in the Thread Environment Block. It then generates an segmentation fault (by writing to address 0) in order to demonstrate that the exception handler can run, fix the problem, and tell the OS to resume and try the problematic instruction again.

This example did not compile in my favorite C++ development environment for Windows, which is MSYS2. MSYS2 comes with a mingw-w64 GCC compiler. I don't know much about x86 assembly but I managed to port the example and get it to run. The main thing I had to change was the syntax of the inline assembly. Here is the code:


/* Basic demonstration of Win32 structured exception handling (SEH).

This code is based on Figure 3 (MYSEH.CPP) from this article:

    https://www.microsoft.com/msj/0197/exception/exception.aspx

Originally written by Matt Pietrek for the January 1997 Microsoft
Systems Journal.

Modified in 2016 by David E. Grayson to work with gcc.
*/

#include <windows.h>
#include <stdio.h>

DWORD scratch = 10;

EXCEPTION_DISPOSITION __cdecl
_except_handler(
    struct _EXCEPTION_RECORD * ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT * ContextRecord,
    void * DispatcherContext)
{
    // Indicate that we made it to our exception handler.
    printf("Hello from an exception handler\n");  fflush(stdout);

    // Change EAX in the context record so that it points to some
    // place where we can successfully write.
    ContextRecord->Eax = (DWORD_PTR)&scratch;

    // Tell the OS to restart the faulting instruction.
    return ExceptionContinueExecution;
}

int main()
{
    __asm__(                        // Build EXCEPTION_REGISTRATION record:
        "push    %0\n"              // Bytes 4 to 7: Address of handler function
        "push    %%fs:0\n"          // Bytes 0 to 3: Address of previous handler
        "movl    %%esp, %%fs:0\n"   // Install new EXECPTION_REGISTRATION
        :
        : "r" ((DWORD_PTR)_except_handler)
        );

    __asm__(
        "movl    $0, %eax\n"        // Zero out EAX
        "movl    $1, (%eax)\n"      // Write to EAX to deliberately cause a fault
        );

    printf("After writing!\n"); fflush(stdout);

    __asm__(                        // Remove our EXCEPTION_REGISTRATION record
        "movl    (%esp), %eax\n"    // Get pointer to previous record
        "movl    %eax, %fs:0\n"     // Install previous record
        "addl    $8, %esp\n"        // Clean our EXCEPTION_REGISTRATION off stack
        );

    printf("scratch = %d\n", scratch);

    return 0;
}

I compiled the code in a MinGW-w64 32-bit Shell, with /mingw32/bin/g++, using the command g++ -g3 -O0 myseh.cpp. When I run a.exe, the output is:

Hello from an exception handler
After writing!
scratch = 1

So this shows that our exception handler really did work!

Using less assembly

The code above worked, but I would not use it in production because it contains inline assembly that does sketchy things to the stack and registers without telling the compiler about it. We can make it a little bitter by using functions and structs provided by Windows headers to manipulate the thread environment block (which were probably not available in 1997 when Matt Pietrek wrote his article).


/* Basic demonstration of Win32 structured exception handling (SEH).

This code is based on Figure 3 (MYSEH.CPP) from this article:

    https://www.microsoft.com/msj/0197/exception/exception.aspx

Originally written by Matt Pietrek for the January 1997 Microsoft
Systems Journal.

Modified in 2016 by David E. Grayson to work with gcc and use less assembly.
*/

#include <windows.h>
#include <winternl.h>
#include <stdio.h>

DWORD scratch = 10;

EXCEPTION_DISPOSITION __cdecl
_except_handler(
    struct _EXCEPTION_RECORD * ExceptionRecord,
    void * EstablisherFrame,
    struct _CONTEXT * ContextRecord,
    void * DispatcherContext)
{
    // Indicate that we made it to our exception handler.
    printf("Hello from an exception handler\n");  fflush(stdout);

    // Change EAX in the context record so that it points to some
    // place where we can successfully write.
    ContextRecord->Eax = (DWORD_PTR)&scratch;

    // Tell the OS to restart the faulting instruction.
    return ExceptionContinueExecution;
}

int main()
{
    NT_TIB * teb = (NT_TIB *)NtCurrentTeb();

    // Install our handler at the beginning of the list.
    EXCEPTION_REGISTRATION_RECORD reg;
    reg.prev = teb->ExceptionList;
    reg.handler = (PEXCEPTION_ROUTINE)_except_handler;
    teb->ExceptionList = &reg;

    __asm__(
        "movl $0, %%eax\n"        // Zero out EAX
        "movl $1, (%%eax)\n"      // Write to EAX to deliberately cause a fault
        ::: "memory", "eax"
        );

    printf("After writing!\n"); fflush(stdout);

    // Remove our handler from the list.
    teb->ExceptionList = reg.prev;

    printf("scratch = %d\n", scratch);

    return 0;
}

We have to use two casts in the code above. First, we cast the output of NtCurrentTeb() because the struct type it points to by default is not very useful and just has a lot of fields with names like Reserved1. Second, we cast _except_handler because there is a disagreement about whether the exception handler should use the __cdecl calling convention or __stdcall. Both calling conventions seem to work, but since the calling convention of our _except_handler function does not match the calling convention of the handler member of the struct, we need to use a type-cast to satisfy the type-checking the GCC does at compile time. I have noticed cases like this in the past, where I had to change the calling convention of something to get it to compile with GCC, but presumably it would compile fine with the Microsoft C compiler. The function prototype of _except_handler in Microsoft's headers uses __cdecl, while the type definition of EXCEPTION_ROUTINE uses NTAPI, which means __stdcall.

What about 64-bit?

Apparently structured exception handling for 64-bit Windows is done in a totally different way, so you can't easily adapt the code above to work in 64-bit mode. More info about x64 Structured Exception Handling is available from OSR Online.

What's the point?

Microsoft's C compiler emits code similar to what I have above when you use the __try, __except, and __finally keywords. GCC does not yet support these keywords, but Clang has partial support for them. I have heard (but not verified) that WebKit uses SEH, so if we want to compile WebKit with GCC, someone needs to add SEH to GCC first. Or maybe we could compile WebKit but we would have to somewhat disable its sandboxing features. I haven't actually tried to compile WebKit with GCC yet.

Friday, October 9, 2015

Tuesday, June 2, 2015

USB CDC ACM braindump

I just dumped a lot of stuff I know about USB CDC ACM devices into a StackOverflow answer. Check it out if you want to learn more about the standard way to make a USB device that has a virtual serial port.

Friday, May 29, 2015

Ways to return a string from a C function

I am working on a C library and I need to have a flexible, easy, efficient way to return strings to the user. See my gist on this topic: https://gist.github.com/DavidEGrayson/db13d38cbe5c95db64c4.