2.07.2013

Web server na STM32F4Discovery

Przez sieć możemy w prosty sposób sterować STM32F4Discovery. Dla przykładu program do zapalania i gaszenia diod LED znajdujących się na płytce przez stronę WWW.

Zaczynamy od konfiguracji interfejsu i podpięcia się do zdarzenia tak, aby odbierać żądania HTTP przychodzące na port 80.

Adapter.Start(new byte[] {0x5c, 0x86, 0x4a, 0x00, 0x00, 0xdd},
                "stm32f4", SPI.SPI_module.SPI3,
                Stm32F4Discovery.FreePins.PD1, Stm32F4Discovery.FreePins.PA15);

Adapter.ListenToPort(80);
Adapter.OnHttpReceivedPacketEvent += OnHttpReceivedPacketEvent;

Dodatkowo zdefiniujemy pomocniczy słownik, aby łatwo wybierać odpowiednią diodę na podstawie koloru. Red, Blue, Orange i Green to stałe napisy, które pojawiać się będą w żądaniu. Na przykład wejście na stronę http://stm32f4/led.svc?Orange (tak, zamiast IP można podać nazwę z konfiguracji interfejsu) będzie powodowało zmianę stanu diody pomarańczowej.

_leds = new Hashtable
            {
                {Red, new OutputPort(Stm32F4Discovery.LedPins.Red, false)},
                {Blue, new OutputPort(Stm32F4Discovery.LedPins.Blue, false)},
                {Orange, new OutputPort(Stm32F4Discovery.LedPins.Orange, false)},
                {Green, new OutputPort(Stm32F4Discovery.LedPins.Green, false)}
            };
Została jeszcze implementacja metody obsługującej zdarzenia OnHttpReceivedPacketEvent. Na początku wyciągamy ze ścieżki  zawartość zapytania (po znaku ?) i plik. Na podstawie tych wartości decydujemy czy obsłużyć żądanie czy zwrócić HTTP 404 (linia 34) i którą diodę przełączyć (linia 16). W StringBuilderze produkujemy stronę (odpowiedź serwera), która składa się z 4 linków o odpowiednich adresach.

private static void OnHttpReceivedPacketEvent(HttpRequest request)
{
    lock (SyncRoot)
    {
        int filePos = request.Path.LastIndexOf('/');
        string file = filePos == -1 ? String.Empty : request.Path.Substring(filePos + 1);

        int queryPos = file.LastIndexOf('?');
        string query = queryPos == -1 ? String.Empty : file.Substring(queryPos + 1);

        if (queryPos != -1)
            file = file.Substring(0, queryPos);

        if (file == "led.svc")
        {
            var led = _leds[query] as OutputPort;
            if (led != null)
                led.Write(!led.Read());

            var sb = new StringBuilder("<html><head></head><body>");
            foreach (string key in _leds.Keys)
                sb.Append("<a href=\"/led.svc?" + key + "\">" + key + "</a> ");
            sb.Append("</body></html>");

            byte[] responseBuffer = Encoding.UTF8.GetBytes(sb.ToString());
            using (var responseStream = new MemoryStream(responseBuffer))
            {
                request.SendResponse(new HttpResponse(responseStream));
            }

            return;
        }

        request.SendNotFound();
    }
}

Pełny kot: DemoEnc28J60mIP_WebSrv

Brak komentarzy:

Prześlij komentarz