add wiki pages

This commit is contained in:
aanper
2020-08-15 09:57:12 +03:00
parent 7951fcc1ae
commit cbfc5fad53
25 changed files with 909 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
List of [FURI](FURI) records for exchange data between applications.
# Interrupts
* `/irq/buttons` — raw button press/release events.
|Name|Type|Size|
|---|---|---|
|Button|0 &mdash; Up<br/>1 &mdash; Down<br/>2 &mdash; Right<br/>3 &mdash; Left<br/>4 &mdash; Ok<br/>5 &mdash; Back|1|
|State|1 &mdash; pressed<br/>0 &mdash; released|1|
* `/irq/charge` &mdash; charge state event
# UI
|Name|Type|Size|
|---|---|---|
|State|1 &mdash; charge start<br/>0 &mdash; charge stop|1|
* `/ui/fb` &mdash; pointer to current framebuffer
|Name|Type|Size|
|---|---|---|
|Framebuffer pointer|`uint8_t[DISPLAY_WIDTH][DISPAY_HEIGHT]`|4|
* `/ui/leds` &mdash; user led state
Led state is overrided by charge state (red when charging, green when charged).
|Name|Type|Size|
|---|---|---|
|Red|pwm value (0..255)|1|
|Green|pwm value (0..255)|1|
|Blue|pwm value (0..255)|1|
|Enable|1 &mdash; user led enabled<br/>0 &mdash; user led disabled (for manual led control)|1|
* `/ui/buttons_event` &mdash; button press/release events after debounce.
|Name|Type|Size|
|---|---|---|
|Button|0 &mdash; Up<br/>1 &mdash; Down<br/>2 &mdash; Right<br/>3 &mdash; Left<br/>4 &mdash; Ok<br/>5 &mdash; Back|1|
|State|1 &mdash; pressed<br/>0 &mdash; released|1|
* `/ui/buttons_state` &mdash; current button state after debounce.
|Name|Type|Size|
|---|---|---|
|Up|1 &mdash; pressed<br/>0 &mdash; released|1|
|Down|1 &mdash; pressed<br/>0 &mdash; released|1|
|Right|1 &mdash; pressed<br/>0 &mdash; released|1|
|Left|1 &mdash; pressed<br/>0 &mdash; released|1|
|Ok|1 &mdash; pressed<br/>0 &mdash; released|1|
|Back|1 &mdash; pressed<br/>0 &mdash; released|1|
* `/ui/fullscreen` &mdash; fullscreen mode state
|Name|Type|Size|
|---|---|---|
|State|1 &mdash; fullscreen<br/>0 &mdash; no fullscreen|1|

54
wiki/fw/FURI.md Normal file
View File

@@ -0,0 +1,54 @@
Flipper Universal Registry Implementation or FURI is important part of Flipper firmware. It is used to:
* application control (start, exit, switch between active)
* data exchange between application (create/open channel, subscribe and push messages or read/write values)
* non-volatile data storage for application (create/open value and read/write)
# Application registry and control (FURIAC)
### Start and change application wrokflow
* `FuriApp furiac_start(void(app*)(void*), char* name, void* param)` simply starts application. It call `app` entrypoint with `param` passed as argument. Useful for daemon applications and pop-up.
* `FuriApp furiac_switch(void(app*)(void*), char* name, void* param)` swtich to other application. FURI **stop current app**, call `app` entrypoint with `param` passed as argument and save current application entrypoint to `prev` field in current application registry. Useful for UI or "active" application.
### Exit application
* `furiac_exit(void* param)` stop current application (stop thread and clear application's stack), start application from `prev` entry in current application registry, cleanup current application registry.
* `furiac_kill(FuriApp app)` stop specified `app` without returning to `prev` application.
# Data exchange
* `FuriRecord furi_create(char* name)` creates named FURI record. Returns NULL if registry have not enough memory for creating.
* `FuriRecord furi_open(char* name, bool solo, bool no_mute)` opens existing FURI record by name. Returns NULL if record does not exist. If `solo` is true **another applications handlers set into "muted" state**. When appication has exited or record has closed, all handlers is unmuted. It may be useful for concurrently acces to resources like framebuffer or beeper. If `no_mute` is true, another applications cannot mute this handler.
* `bool furi_close(FuriRecord record)` close handler and unmute anothers.
* `bool furi_read(FuriRecord record, void* data, size_t size)` read message from record. Returns true if success, false otherwise.
* `bool furi_write(FuriRecord record, const void* data, size_t size)` write message to record. Returns true if success, false otherwise (handler gone or muted).
* `bool furi_take(FuriRecord record, void* data, size_t size)` works as `furi_read` but lock global mutex. It can be useful if records contain pointer to buffer which you want to change. You must call `furi_give` after operation on data and you cannot block executing between `take` and `give` calls
* `bool furi_give(FuriRecord record, const void* data, size_t size)` works as `furi_wrte` but unlock global mutex.
* `bool furi_global_take()` lock global mutex (as `furi_take` but without read)
* `boold furi_global_give()` unlock global mutex ((as `furi_give` but without write))
* `bool furi_unmute(FuriRecord record)` unmutes muted record.
* `bool furi_mute(FuriRecord record)` mutes unmuted record.
* `bool furi_subscribe(FuriRecord record, void(cb*)(const void* data, size_t size))` set record change callback.
* `bool furi_state_subscribe(FuriRecord record, void(cb*)(bool muted))` set record state change callback (mute/unmute). For example, you can unmute itself after some application open same record, or redraw your application UI when popup application ends.
# Usage example
_Diagram below describes furi states_
![FURI states](https://github.com/Flipper-Zero/wiki/raw/master/images/furi_states.png)
* After start, init code run some applications: in this example there is status bar, a background task and Home screen
* Status bar open access to framebuffer by opening "/ui/fb" FURI record
* "Home screen" call "Menu" application by `furiac_switch`. "Home screen" application stops and then "Menu" application starts.
* "Menu" application call "Your cool app" the same way. It also get access to framebuffer by open "/ui/fb" FURI record
* If "Your cool app" needs some backend app, it call this by `furiac_start` and then kill by `furiac_kill`
* If background task needs to show popup message (for example "Low battery") it can call new app or simply open "/ui/fb" record.
* When "/ui/fb" record is opened by popup message, FURI mute framebuffer handle in "Your cool app". This prevent to overwrite popup message by application drawing.
* "Status bar" framebuffer handle also is muted, but it call `furi_unmute` and unmute itself.
* After popup message is closed by `furiac_exit` or closing "/ui/fb", FURI unmute previous muted "Your cool app" framebuffer handle.
_Status bar also get mute and unmute itself every time when Home screen, Menu or "Your cool app" open framebuffer but diagramm not show it_
# Data storage
* `furi_create_var(char* name)` create static-like value handler. You can use all furi_ calls for

117
wiki/fw/Firmware.md Normal file
View File

@@ -0,0 +1,117 @@
_Overview of Flipper firmware architecture:_
![FW arch](https://github.com/Flipper-Zero/wiki/raw/master/images/flipper_fw_arch.png)
# HAL
We use STM32 HAL/LL. Description available here: [dm00105879.pdf](https://github.com/Flipper-Zero/wiki/raw/master/dm00105879-description-of-stm32f4-hal-and-ll-drivers-stmicroelectronics.pdf)
## Flipper HAL
Some flipper-specific implementation of gpio/HAL:
* Init gpio pin: `app_gpio_init`
* Fast write gpio (inline): `app_gpio_write`
* Fast read gpio (inline): `app_gpio_read`
* Microsecond delay `delay_us`
* Set PWM on timer's pin: `pwm_set`
Files location: `/app/app_hal.[ch]`
# OS
We use FreeRTOS 10.0.1 for sheduling. Documentation available on [freertos.org](https://www.freertos.org/a00106.html).
Files location for L476 version: `/target_prod/Middlewares/Third_Party/FreeRTOS`
**[Timers map](Timers)**
# Platform code
CMSIS, Freertos and HAL files are generated by CubeMX.
You can find platform code for L476 version in `target_prod` folder:
* `Drivers/STM32L4xx_HAL_Driver` hardware abstraction layer
* `Drivers/CMSIS` — ARM specific code
* `Inc` `Src` — CubeMX generated headers & code
* `Middlewares/Third_Party/FreeRTOS/Source` — freeRTOS
* `deploy.sh` — flash firmware to device
* `STM32L476RGTx_FLASH.ld` — linker script
* `startup_stm32l476xx.s` — board startup/initialization assembler code
* `flipperzero_l476.ioc` — CubeMX project file
You can regenerate platform code:
1. Download CubeMX from [st.com](https://www.st.com/en/development-tools/stm32cubemx.html)
2. Open `*.ioc` file
3. Click `generate code`
4. After regenerating, look at git status, regenerating may broke some files.
## Arduino compatibility
There are some arduino-style defines (digitalWrite, delay, etc.). Include `Arduino.h` from `/app/Arduino.h`
## Debug print
You can use `pintf` to write any message to debug UART. UART specify in `Makefile` as `-DDEBUG_UART=<>`.
Implementation of write method located at `/app/write.c`
# Flipper Universal Registry Implementation (FURI)
FURI is used to:
* application control (start, exit, switch between active)
* data exchange between application (create/open channel, subscribe and push messages or read/write values)
* non-volatile data storage for application (create/open value and read/write)
Read more at [FURI page](FURI)
# FS
File system is used to volaile storage some files (config, application data, etc.). There are some folders mounted to different volumes:
* `/usr` for store static data like assets, menu items. Build system add files to usr while building. It can be useful for exchange some static data between application. For example, your app can add link to itself to Plugins menu items file, user will see your app and can call it from this menu.
* Specially `/usr/etc-default` folder contains default configs for apps. Bootloader has `factory default` options to reset applications config. Also when new app is bootstapping, system copy files from default config folder to `/etc`.
* `/etc` for store configs of application. This volume not overwrite during flashing.
* `/var` for store some application data (saved keys, application database, logs). This volume also not overwrite during flashing.
* `/media/*` mounted if SD card is inserted.
# Flipper applications
Each flipper functionality except OS/HAL/FURI doing by Flipper application. Some application are called at startup, the rest are called by the user (for example, from menu).
**[List of Flipper applications](Flipper-applications)**
For exchange data between application each app expose own record in FURI. You can subscribe on/read record to get data from application and write to record to send data to application.
**[List of FURI records](FURI-records-list)**
# Flipper libraries
Unlike applications that run after startup, libraries are a collection of constants, types, or functions that the user can call from within the application.
**[List of Flipper libraries](Flipper-libraries)**
# Bootloader
After start, bootloader run first. It can:
1. Runs main firmware
2. Reflashes firmware from temporary area after updating from usb/bluetooth
3. Restores factory default firmware for protected flash area
4. Restores application settings to default by clearing `/etc` volume
# Building
## Build in docker container (main way)
1. Install [docker compose](https://docs.docker.com/compose/install/)
2. After startup you should run `docker-compose up -d` to run the container.
3. Then you can run `docker-compose exec dev make` to build application.
If Dockerfile is changed you should run `docker-compose down` and `docker-compose build` for rebuild the image.
## Build in IDE
* Arduino IDE (in progress)
* PlatformIO (in progress)

View File

View File

61
wiki/fw/Timers.md Normal file
View File

@@ -0,0 +1,61 @@
## Tim1
~1 kHz, PWM
* Ch1 -- red led
* Ch2 -- green led
* Ch3 -- blue led
## Tim2
46/48 kHz, interrupt for IR. Ch4 -- IR TX
## Tim4
~1 kHz, PWM
* Ch1 -- backlight
## Tim5
Variable freq. PWM. Ch4 -- speaker.
## Tim8
* Ch2 -- iButton emulate
## Tim15
125 kHz. Square generator and interrupt/RFID pull.
* Ch1 -- RFID OUT (square generator)
* Ch2 -- RFID Pull
# Devices
## Speaker
Tim5 ch4
## Blue led
Tim1, Tim3, Tim8
## Red led
Tim1
## Green led
Tim15, Tim1, Tim8
## Backlight
Tim16, Tim4
## IR TX
Tim2 ch4
## RFID out
Tim15, Tim1
## RFID pull
Tim15, Tim1, Tim8
## iButton
Tim3, Tim8