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"); | ||||
| @ -59,3 +59,26 @@ 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: | ||||
| 
 | ||||
|  | ||||
|  | ||||
| 
 | ||||
| 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`. | ||||
| 
 | ||||
| Зырим как светодиод пытается мигать. | ||||
| 
 | ||||
|  | ||||
| 
 | ||||
| _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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 coreglitch
						coreglitch