led blink example

* led blink example

* restore tests

* Update FURI_and_examples.md
This commit is contained in:
coreglitch 2020-08-26 07:56:33 +06:00 committed by GitHub
parent 2e023ffcda
commit bee159f435
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 211 additions and 101 deletions

View File

@ -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);
}
*/

View File

@ -1,2 +0,0 @@
void furi_test_app(void*);

View 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);
}
}

View File

@ -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
};

View File

@ -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;

View File

@ -1,2 +0,0 @@
void flipper_test_app(void* p);

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View 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`_

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e386746c69e0685a45f8cd320239e825b23e17f07ab272a764cb08b54796a1e2
size 411159

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:21d591754f159cc9c2e1870cf88fbae2bd69573c4a3b3721e9c2857d6265d44c
size 17359

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:3d54ae19be7820c2db4f2d0177ecfee2e3dd16a387df49543876039dbfe92fa2
size 14717