led blink example
* led blink example * restore tests * Update FURI_and_examples.md
This commit is contained in:
parent
2e023ffcda
commit
bee159f435
@ -1,81 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#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);
|
||||
}
|
||||
*/
|
@ -1,2 +0,0 @@
|
||||
|
||||
void furi_test_app(void*);
|
16
applications/examples/blink.c
Normal file
16
applications/examples/blink.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
};
|
@ -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;
|
||||
|
@ -1,2 +0,0 @@
|
||||
|
||||
void flipper_test_app(void* p);
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
void osDelay(uint32_t ms) {
|
||||
printf("[DELAY] %d ms\n", ms);
|
||||
// printf("[DELAY] %d ms\n", ms);
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
|
111
wiki/devlog/FURI_and_examples.md
Normal file
111
wiki/devlog/FURI_and_examples.md
Normal file
@ -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`_
|
3
wiki_static/application_examples/example_blink.gif
Normal file
3
wiki_static/application_examples/example_blink.gif
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e386746c69e0685a45f8cd320239e825b23e17f07ab272a764cb08b54796a1e2
|
||||
size 411159
|
3
wiki_static/application_examples/gpio_pa8.png
Normal file
3
wiki_static/application_examples/gpio_pa8.png
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:21d591754f159cc9c2e1870cf88fbae2bd69573c4a3b3721e9c2857d6265d44c
|
||||
size 17359
|
3
wiki_static/application_examples/leds.png
Normal file
3
wiki_static/application_examples/leds.png
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3d54ae19be7820c2db4f2d0177ecfee2e3dd16a387df49543876039dbfe92fa2
|
||||
size 14717
|
Loading…
Reference in New Issue
Block a user