diff --git a/applications/app_example/app_example.c b/applications/app_example/app_example.c deleted file mode 100644 index cbbebd5f..00000000 --- a/applications/app_example/app_example.c +++ /dev/null @@ -1,81 +0,0 @@ -#include -#include "flipper.h" -#include "debug.h" - -void furi_widget(void* param); -void furi_test_app(void* param); -void furi_next_test_app(void* param); - -/* -widget simply print ping message -*/ -void furi_widget(void* param) { - FILE* debug_uart = get_debug(); - - fprintf(debug_uart, "start furi widget: %s\n", (char*)param); - - while(1) { - fprintf(debug_uart, "furi widget\n"); - delay(10); - } -} - -/* -it simply start, then start child widget, wait about 1 sec (with ping evey 200 ms), -kill the widget, continue with 500 ms ping. -*/ -void furi_test_app(void* param) { - - uint8_t cnt = 0; - - while(1) { - fprintf(debug_uart, "furi test app %d\n", cnt); - delay(10); - - if(cnt == 2) { - fprintf(debug_uart, "go to next app\n"); - furiac_switch(furi_next_test_app, "next_test", NULL); - fprintf(debug_uart, "unsuccessful switch\n"); - while(1) { - delay(1000); - } - } - - cnt++; - } -} - -void furi_next_test_app(void* param) { - FILE* debug_uart = get_debug(); - - fprintf(debug_uart, "start next test app\n"); - - delay(10); - - fprintf(debug_uart, "exit next app\n"); - furiac_exit(NULL); - - while(1) { - // this code must not be called - fprintf(debug_uart, "next app: something went wrong\n"); - delay(10); - } -} - -/* -FILE* debug_uart = get_debug(); - -fprintf(debug_uart, "hello Flipper!\n"); - -GpioPin red_led = {LED_RED_GPIO_Port, LED_RED_Pin}; - -app_gpio_init(red_led, GpioModeOutput); - - -while(1) { - delay(100); - app_gpio_write(red_led, true); - delay(100); - app_gpio_write(red_led, false); -} -*/ \ No newline at end of file diff --git a/applications/app_example/app_example.h b/applications/app_example/app_example.h deleted file mode 100644 index 40d5ec13..00000000 --- a/applications/app_example/app_example.h +++ /dev/null @@ -1,2 +0,0 @@ - -void furi_test_app(void*); \ No newline at end of file diff --git a/applications/examples/blink.c b/applications/examples/blink.c new file mode 100644 index 00000000..9d59e739 --- /dev/null +++ b/applications/examples/blink.c @@ -0,0 +1,16 @@ +#include "flipper.h" + +void application_blink(void* p) { + // create pin + GpioPin led = {.pin = GPIO_PIN_8, .port = GPIOA}; + + // configure pin + pinMode(led, GpioModeOutput); + + while(1) { + digitalWrite(led, HIGH); + delay(500); + digitalWrite(led, LOW); + delay(500); + } +} \ No newline at end of file diff --git a/applications/startup.h b/applications/startup.h index 7c93013a..31bac7d0 100644 --- a/applications/startup.h +++ b/applications/startup.h @@ -1,13 +1,24 @@ #pragma once #include "furi.h" -#include "tests/test_index.h" typedef struct { FlipperApplication app; const char* name; } FlipperStartupApp; +#ifdef TEST +void flipper_test_app(void* p); +#endif + +void application_blink(void* p); + const FlipperStartupApp FLIPPER_STARTUP[] = { - {.app = flipper_test_app, .name = "test app"} + #ifdef TEST + {.app = flipper_test_app, .name = "test app"}, + #endif + + #ifdef EXAMPLE_BLINK + {.app = application_blink, .name = "blink"}, + #endif }; \ No newline at end of file diff --git a/applications/tests/furiac_test.c b/applications/tests/furiac_test.c index d5e88121..bc5a188a 100644 --- a/applications/tests/furiac_test.c +++ b/applications/tests/furiac_test.c @@ -121,6 +121,8 @@ bool furi_ac_switch_exit(FILE* debug_uart) { delay(10); // wait while task do its work + seq.sequence[seq.count] = '\0'; + if(strcmp(seq.sequence, "ABA/") != 0) { fprintf(debug_uart, "wrong sequence: %s\n", seq.sequence); return false; diff --git a/applications/tests/test_index.h b/applications/tests/test_index.h deleted file mode 100644 index 9b5204ee..00000000 --- a/applications/tests/test_index.h +++ /dev/null @@ -1,2 +0,0 @@ - -void flipper_test_app(void* p); \ No newline at end of file diff --git a/target_lo/Inc/flipper_hal.h b/target_lo/Inc/flipper_hal.h index 561ddfe2..f93cde3e 100644 --- a/target_lo/Inc/flipper_hal.h +++ b/target_lo/Inc/flipper_hal.h @@ -17,7 +17,7 @@ typedef enum { } GpioMode; typedef struct { - uint32_t port; + const char* port; uint32_t pin; GpioMode mode; } GpioPin; @@ -27,9 +27,9 @@ void app_gpio_init(GpioPin gpio, GpioMode mode); inline void app_gpio_write(GpioPin gpio, bool state) { if(gpio.pin != 0) { if(state) { - printf("[GPIO] %d:%d on\n", gpio.port, gpio.pin); + printf("[GPIO] %s%d on\n", gpio.port, gpio.pin); } else { - printf("[GPIO] %d:%d off\n", gpio.port, gpio.pin); + printf("[GPIO] %s%d off\n", gpio.port, gpio.pin); } } else { printf("[GPIO] no pin\n"); @@ -58,4 +58,27 @@ inline void app_tim_pulse(uint32_t width) { inline void app_tim_stop() { printf("[TIM] stop\n"); -} \ No newline at end of file +} + +#define GPIOA "PA" +#define GPIOB "PB" +#define GPIOC "PC" +#define GPIOD "PD" +#define GPIOE "PE" + +#define GPIO_PIN_0 0 +#define GPIO_PIN_1 1 +#define GPIO_PIN_2 2 +#define GPIO_PIN_3 3 +#define GPIO_PIN_4 4 +#define GPIO_PIN_5 5 +#define GPIO_PIN_6 6 +#define GPIO_PIN_7 7 +#define GPIO_PIN_8 8 +#define GPIO_PIN_9 9 +#define GPIO_PIN_10 10 +#define GPIO_PIN_11 11 +#define GPIO_PIN_12 12 +#define GPIO_PIN_13 13 +#define GPIO_PIN_14 14 +#define GPIO_PIN_15 15 diff --git a/target_lo/Makefile b/target_lo/Makefile index 41e0c8de..e4d83030 100644 --- a/target_lo/Makefile +++ b/target_lo/Makefile @@ -25,6 +25,8 @@ Src/main.c CPP_SOURCES = ../core/app.cpp +# Core + C_SOURCES += ../core/debug.c C_SOURCES += ../core/furi.c C_SOURCES += ../core/furi_ac.c @@ -32,9 +34,28 @@ C_SOURCES += Src/flipper_hal.c C_SOURCES += Src/lo_os.c C_SOURCES += Src/lo_hal.c +# C defines +C_DEFS = \ +-DUSE_HAL_DRIVER \ +-DSTM32L476xx \ +-DBUTON_INVERT=false \ +-DDEBUG_UART=huart1 + +# System applications + +ifeq ($(TEST), 1) C_SOURCES += ../applications/tests/furiac_test.c C_SOURCES += ../applications/tests/furi_record_test.c C_SOURCES += ../applications/tests/test_index.c +C_DEFS += -DTEST +endif + +# User application + +ifeq ($(EXAMPLE_BLINK), 1) +C_SOURCES += ../applications/examples/blink.c +C_DEFS += -DEXAMPLE_BLINK +endif ####################################### # binaries @@ -52,12 +73,6 @@ BIN = $(CP) -O binary -S # CFLAGS ####################################### -# C defines -C_DEFS = \ --DUSE_HAL_DRIVER \ --DSTM32L476xx \ --DBUTON_INVERT=false \ --DDEBUG_UART=huart1 # C includes C_INCLUDES = \ @@ -90,6 +105,14 @@ LDFLAGS = $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc- # default action: build all all: $(BUILD_DIR)/$(TARGET) +example_blink: + EXAMPLE_BLINK=1 make + $(BUILD_DIR)/$(TARGET) + +test: + TEST=1 make + $(BUILD_DIR)/$(TARGET) + ####################################### # build the application diff --git a/target_lo/Src/flipper_hal.c b/target_lo/Src/flipper_hal.c index 8f20d3dd..11b6b80a 100644 --- a/target_lo/Src/flipper_hal.c +++ b/target_lo/Src/flipper_hal.c @@ -13,15 +13,15 @@ void app_gpio_init(GpioPin gpio, GpioMode mode) { switch(mode) { case GpioModeInput: - printf("[GPIO] %d:%d input\n", gpio.port, gpio.pin); + printf("[GPIO] %s%d input\n", gpio.port, gpio.pin); break; case GpioModeOutput: - printf("[GPIO] %d:%d push pull\n", gpio.port, gpio.pin); + printf("[GPIO] %s%d push pull\n", gpio.port, gpio.pin); break; case GpioModeOpenDrain: - printf("[GPIO] %d:%d open drain\n", gpio.port, gpio.pin); + printf("[GPIO] %s%d open drain\n", gpio.port, gpio.pin); break; } diff --git a/target_lo/Src/lo_os.c b/target_lo/Src/lo_os.c index dd83b4ec..b2d9316e 100644 --- a/target_lo/Src/lo_os.c +++ b/target_lo/Src/lo_os.c @@ -6,7 +6,7 @@ #include void osDelay(uint32_t ms) { - printf("[DELAY] %d ms\n", ms); + // printf("[DELAY] %d ms\n", ms); usleep(ms * 1000); } diff --git a/wiki/devlog/FURI_and_examples.md b/wiki/devlog/FURI_and_examples.md new file mode 100644 index 00000000..8e4f8f72 --- /dev/null +++ b/wiki/devlog/FURI_and_examples.md @@ -0,0 +1,111 @@ +One of the most important component of Flipper Core is [FURI](FURI) (Flipper Universal Registry Implementation). It helps control the applications flow, make dynamic linking and interaction between applications. + +In fact, FURI is just wrapper around RTOS thread management and mutexes, and callback management. + +In this article we create few application, interact between apps, use OS functions and interact with HAL. + +# Simple Blink app + +First, let's create a simple led blinking application. + +## General agreements + +Flipper application is just a function: + +```C +void application_name(void* p) { + // Setup + + while(1) { + // Loop + } +} +``` + +1. `void* p` is arbitrary pointer that may be used for pass parameters to application at launch (like argc/argv in POSIX). +2. Application must never attempt to return or exit from their implementing function. +3. Avoid long cycles without any "waits" or "blocking" like `delay` or `xQueueReceive`, otherwise your app will blocking overall Flipper work. +4. Do not create static variables inside function or global variables. Use only local variables. We plan to add virual in-RAM filesystem to save any persistent data. + +## Preparing for launch + +We will use integrated LED. Look at the schematic: + +![](https://github.com/Flipper-Zero/flipperzero-firmware-community/raw/master/wiki_static/application_examples/leds.png) +![](https://github.com/Flipper-Zero/flipperzero-firmware-community/raw/master/wiki_static/application_examples/gpio_pa8.png) + +This led connect between power rail and GPIO PA8 and we should configure this pin as open drain to properly control led behaviour. + +You can find GPIO API in `target_*/flipper_hal.h`. Or if you prefer to use Arduino API, you can find bindings in `core/flipper.h`. + +For work with pin we should: + +1. Create `GpioPin` instance and specify pin and port. +2. Configure mode of pin by `pinMode` function. +3. Control state of pin by `digitalWrite` function. + +## Creating application + +1. Create new file (for example, `blink.c`) in `applications` folder. +2. Create code like this: + +```C +#include "flipper.h" + +void application_blink(void* p) { + // create pin + GpioPin led = {.pin = GPIO_PIN_8, .port = GPIOA}; + + // configure pin + pinMode(led, GpioModeOutput); + + while(1) { + digitalWrite(led, HIGH); + delay(500); + digitalWrite(led, LOW); + delay(500); + } +} +``` +3. To start your application on Flipper startup, add it to autorun: + * in `applications/startup.h` add prototype of main application function: + + ```C + void application_blink(void* p); + ``` + + * add entry to `FLIPPER_STARTUP` array (pointer to application function and application name): + + ```C + const FlipperStartupApp FLIPPER_STARTUP[] = { + #ifdef TEST + {.app = flipper_test_app, .name = "test app"} + #endif + + // user applications: + + , {.app = application_blink, .name = "blink"} + }; + ``` + +4. Add your application file to Makefile (for each target, `target_lo/Makefile` and `target_f1/Makefile`, we add one common makefile later): + +``` +# User application + +C_SOURCES += ../applications/blink.c +``` + +Build and run for linux (target_lo): + +`docker-compose exec dev make -C target_lo` + +Run: + +`docker-compose exec dev target_lo/build/target_lo`. + +Зырим как светодиод пытается мигать. + +![](https://github.com/Flipper-Zero/flipperzero-firmware-community/raw/master/wiki_static/application_examples/example_blink.gif) + +_You also run found source of this example in `applications/examples/blink.c` and run by `docker-compose exec dev make -C target_lo example_blink`_ diff --git a/wiki_static/application_examples/example_blink.gif b/wiki_static/application_examples/example_blink.gif new file mode 100644 index 00000000..360d8628 --- /dev/null +++ b/wiki_static/application_examples/example_blink.gif @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e386746c69e0685a45f8cd320239e825b23e17f07ab272a764cb08b54796a1e2 +size 411159 diff --git a/wiki_static/application_examples/gpio_pa8.png b/wiki_static/application_examples/gpio_pa8.png new file mode 100644 index 00000000..890dab9a --- /dev/null +++ b/wiki_static/application_examples/gpio_pa8.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:21d591754f159cc9c2e1870cf88fbae2bd69573c4a3b3721e9c2857d6265d44c +size 17359 diff --git a/wiki_static/application_examples/leds.png b/wiki_static/application_examples/leds.png new file mode 100644 index 00000000..2321c6a2 --- /dev/null +++ b/wiki_static/application_examples/leds.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3d54ae19be7820c2db4f2d0177ecfee2e3dd16a387df49543876039dbfe92fa2 +size 14717