[FL-164] Add bootloader version (#417)
* Add bootloader versioning * Move some logic to api-hal-version * Backport to f4 * Dolphin: update version screen layout, make it more readable Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									202673aed1
								
							
						
					
					
						commit
						aa20a78b0e
					
				| @ -1,5 +1,7 @@ | |||||||
| #include "cli_i.h" | #include "cli_i.h" | ||||||
| #include "cli_commands.h" | #include "cli_commands.h" | ||||||
|  | #include <version.h> | ||||||
|  | #include <api-hal-version.h> | ||||||
| 
 | 
 | ||||||
| Cli* cli_alloc() { | Cli* cli_alloc() { | ||||||
|     Cli* cli = furi_alloc(sizeof(Cli)); |     Cli* cli = furi_alloc(sizeof(Cli)); | ||||||
| @ -48,16 +50,31 @@ size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) { | |||||||
|     return api_hal_vcp_rx(buffer, size); |     return api_hal_vcp_rx(buffer, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cli_print_version() { | void cli_print_version(const Version* version) { | ||||||
|     printf("Build date:" BUILD_DATE ". " |     if(version) { | ||||||
|            "Git Commit:" GIT_COMMIT ". " |         printf("\tVersion:\t%s\r\n", version_get_version(version)); | ||||||
|            "Git Branch:" GIT_BRANCH ". " |         printf("\tBuild date:\t%s\r\n", version_get_builddate(version)); | ||||||
|            "Commit Number:" GIT_BRANCH_NUM "."); |         printf( | ||||||
|  |             "\tGit Commit:\t%s (%s)\r\n", | ||||||
|  |             version_get_githash(version), | ||||||
|  |             version_get_gitbranchnum(version)); | ||||||
|  |         printf("\tGit Branch:\t%s\r\n", version_get_gitbranch(version)); | ||||||
|  |     } else { | ||||||
|  |         printf("\tNo build info\r\n"); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cli_motd() { | void cli_motd() { | ||||||
|  |     const Version* version; | ||||||
|     printf("Flipper cli.\r\n"); |     printf("Flipper cli.\r\n"); | ||||||
|     cli_print_version(); | 
 | ||||||
|  |     version = (const Version*)api_hal_version_get_boot_version(); | ||||||
|  |     printf("Bootloader\r\n"); | ||||||
|  |     cli_print_version(version); | ||||||
|  | 
 | ||||||
|  |     version = (const Version*)api_hal_version_get_fw_version(); | ||||||
|  |     printf("Firmware\r\n"); | ||||||
|  |     cli_print_version(version); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cli_nl() { | void cli_nl() { | ||||||
|  | |||||||
| @ -191,6 +191,33 @@ bool dolphin_view_lockmenu_input(InputEvent* event, void* context) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool dolphin_view_idle_down_input(InputEvent* event, void* context) { | ||||||
|  |     furi_assert(event); | ||||||
|  |     furi_assert(context); | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  | 
 | ||||||
|  |     if(event->type != InputTypeShort) return false; | ||||||
|  | 
 | ||||||
|  |     if((event->key == InputKeyLeft) || (event->key == InputKeyRight)) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->idle_view_down, (DolphinViewIdleDownModel * model) { | ||||||
|  |                 model->show_fw_or_boot = !model->show_fw_or_boot; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if(event->key == InputKeyBack) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->idle_view_down, (DolphinViewIdleDownModel * model) { | ||||||
|  |                 model->show_fw_or_boot = 0; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Dolphin* dolphin_alloc() { | Dolphin* dolphin_alloc() { | ||||||
|     Dolphin* dolphin = furi_alloc(sizeof(Dolphin)); |     Dolphin* dolphin = furi_alloc(sizeof(Dolphin)); | ||||||
|     // Message queue
 |     // Message queue
 | ||||||
| @ -255,11 +282,14 @@ Dolphin* dolphin_alloc() { | |||||||
| 
 | 
 | ||||||
|     // Down Idle View
 |     // Down Idle View
 | ||||||
|     dolphin->idle_view_down = view_alloc(); |     dolphin->idle_view_down = view_alloc(); | ||||||
|  |     view_set_context(dolphin->idle_view_down, dolphin); | ||||||
|  |     view_allocate_model( | ||||||
|  |         dolphin->idle_view_down, ViewModelTypeLockFree, sizeof(DolphinViewIdleDownModel)); | ||||||
|     view_set_draw_callback(dolphin->idle_view_down, dolphin_view_idle_down_draw); |     view_set_draw_callback(dolphin->idle_view_down, dolphin_view_idle_down_draw); | ||||||
|  |     view_set_input_callback(dolphin->idle_view_down, dolphin_view_idle_down_input); | ||||||
|     view_set_previous_callback(dolphin->idle_view_down, dolphin_view_idle_back); |     view_set_previous_callback(dolphin->idle_view_down, dolphin_view_idle_back); | ||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
|         dolphin->idle_view_dispatcher, DolphinViewIdleDown, dolphin->idle_view_down); |         dolphin->idle_view_dispatcher, DolphinViewIdleDown, dolphin->idle_view_down); | ||||||
| 
 |  | ||||||
|     // HW Mismatch
 |     // HW Mismatch
 | ||||||
|     dolphin->view_hw_mismatch = view_alloc(); |     dolphin->view_hw_mismatch = view_alloc(); | ||||||
|     view_set_draw_callback(dolphin->view_hw_mismatch, dolphin_view_hw_mismatch_draw); |     view_set_draw_callback(dolphin->view_hw_mismatch, dolphin_view_hw_mismatch_draw); | ||||||
|  | |||||||
| @ -3,6 +3,8 @@ | |||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <gui/elements.h> | #include <gui/elements.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
|  | #include <version.h> | ||||||
|  | #include <api-hal-version.h> | ||||||
| 
 | 
 | ||||||
| static char* Lockmenu_Items[3] = {"Lock", "Set PIN", "DUMB mode"}; | static char* Lockmenu_Items[3] = {"Lock", "Set PIN", "DUMB mode"}; | ||||||
| 
 | 
 | ||||||
| @ -92,25 +94,46 @@ void dolphin_view_lockmenu_draw(Canvas* canvas, void* model) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dolphin_view_idle_down_draw(Canvas* canvas, void* model) { | void dolphin_view_idle_down_draw(Canvas* canvas, void* model) { | ||||||
|     canvas_clear(canvas); |     DolphinViewIdleDownModel* m = model; | ||||||
|  |     const Version* ver; | ||||||
|  |     char buffer[64]; | ||||||
|  | 
 | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|     canvas_set_font(canvas, FontPrimary); |     canvas_set_font(canvas, FontPrimary); | ||||||
|     canvas_draw_str(canvas, 2, 15, "Version info:"); |     canvas_draw_str(canvas, 2, 13, m->show_fw_or_boot ? "Boot Version info:" : "FW Version info:"); | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
|     canvas_draw_str(canvas, 5, 25, TARGET " " BUILD_DATE); |  | ||||||
|     canvas_draw_str(canvas, 5, 35, GIT_BRANCH); |  | ||||||
|     canvas_draw_str(canvas, 5, 45, GIT_BRANCH_NUM " " GIT_COMMIT); |  | ||||||
| 
 | 
 | ||||||
|     char buffer[64]; |     // Hardware version
 | ||||||
|     snprintf( |     snprintf( | ||||||
|         buffer, |         buffer, | ||||||
|         64, |         sizeof(buffer), | ||||||
|         "HW: %d.F%dB%dC%d", |         "HW: %d.F%dB%dC%d %s", | ||||||
|         api_hal_version_get_hw_version(), |         api_hal_version_get_hw_version(), | ||||||
|         api_hal_version_get_hw_target(), |         api_hal_version_get_hw_target(), | ||||||
|         api_hal_version_get_hw_body(), |         api_hal_version_get_hw_body(), | ||||||
|         api_hal_version_get_hw_connect()); |         api_hal_version_get_hw_connect(), | ||||||
|     canvas_draw_str(canvas, 5, 55, buffer); |         api_hal_version_get_name_ptr()); | ||||||
|  |     canvas_draw_str(canvas, 5, 23, buffer); | ||||||
|  | 
 | ||||||
|  |     ver = m->show_fw_or_boot ? api_hal_version_get_boot_version() : | ||||||
|  |                                api_hal_version_get_fw_version(); | ||||||
|  | 
 | ||||||
|  |     if(!ver) { | ||||||
|  |         canvas_draw_str(canvas, 5, 33, "No info"); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     snprintf( | ||||||
|  |         buffer, sizeof(buffer), "%s [%s]", version_get_version(ver), version_get_builddate(ver)); | ||||||
|  |     canvas_draw_str(canvas, 5, 33, buffer); | ||||||
|  | 
 | ||||||
|  |     snprintf( | ||||||
|  |         buffer, sizeof(buffer), "%s [%s]", version_get_githash(ver), version_get_gitbranchnum(ver)); | ||||||
|  |     canvas_draw_str(canvas, 5, 43, buffer); | ||||||
|  | 
 | ||||||
|  |     snprintf( | ||||||
|  |         buffer, sizeof(buffer), "[%s] %s", version_get_target(ver), version_get_gitbranch(ver)); | ||||||
|  |     canvas_draw_str(canvas, 5, 53, buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model) { | void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model) { | ||||||
|  | |||||||
| @ -28,6 +28,10 @@ typedef struct { | |||||||
|     uint32_t butthurt; |     uint32_t butthurt; | ||||||
| } DolphinViewIdleUpModel; | } DolphinViewIdleUpModel; | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  |     bool show_fw_or_boot; | ||||||
|  | } DolphinViewIdleDownModel; | ||||||
|  | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t idx; |     uint8_t idx; | ||||||
| } DolphinViewMenuModel; | } DolphinViewMenuModel; | ||||||
|  | |||||||
| @ -55,7 +55,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ | |||||||
| /* Specify the memory areas */ | /* Specify the memory areas */ | ||||||
| MEMORY | MEMORY | ||||||
| { | { | ||||||
| FLASH (rx)                 : ORIGIN = 0x08000000, LENGTH = 512K | FLASH (rx)                 : ORIGIN = 0x08000000, LENGTH = 32K | ||||||
| RAM1 (xrw)                 : ORIGIN = 0x20000004, LENGTH = 0x2FFFC | RAM1 (xrw)                 : ORIGIN = 0x20000004, LENGTH = 0x2FFFC | ||||||
| RAM_SHARED (xrw)           : ORIGIN = 0x20030000, LENGTH = 10K | RAM_SHARED (xrw)           : ORIGIN = 0x20030000, LENGTH = 10K | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,6 +9,8 @@ | |||||||
| #include <stm32wbxx_ll_gpio.h> | #include <stm32wbxx_ll_gpio.h> | ||||||
| #include <stm32wbxx_hal_flash.h> | #include <stm32wbxx_hal_flash.h> | ||||||
| 
 | 
 | ||||||
|  | #include <version.h> | ||||||
|  | 
 | ||||||
| // Boot request enum
 | // Boot request enum
 | ||||||
| #define BOOT_REQUEST_NONE 0x00000000 | #define BOOT_REQUEST_NONE 0x00000000 | ||||||
| #define BOOT_REQUEST_DFU 0xDF00B000 | #define BOOT_REQUEST_DFU 0xDF00B000 | ||||||
| @ -128,6 +130,10 @@ void rtc_init() { | |||||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); |     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void version_save(void) { | ||||||
|  |     LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR1, (uint32_t)version_get()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void lcd_backlight_on() { | void lcd_backlight_on() { | ||||||
|     LL_GPIO_SetOutputPin(BOOT_LCD_BL_PORT, BOOT_LCD_BL_PIN); |     LL_GPIO_SetOutputPin(BOOT_LCD_BL_PORT, BOOT_LCD_BL_PIN); | ||||||
| } | } | ||||||
| @ -142,6 +148,7 @@ void target_init() { | |||||||
|     clock_init(); |     clock_init(); | ||||||
|     gpio_init(); |     gpio_init(); | ||||||
|     rtc_init(); |     rtc_init(); | ||||||
|  |     version_save(); | ||||||
|     usb_wire_reset(); |     usb_wire_reset(); | ||||||
| 
 | 
 | ||||||
|     // Errata 2.2.9, Flash OPTVERR flag is always set after system reset
 |     // Errata 2.2.9, Flash OPTVERR flag is always set after system reset
 | ||||||
|  | |||||||
| @ -24,6 +24,10 @@ CFLAGS			+= -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc | |||||||
| 
 | 
 | ||||||
| LDFLAGS			+= -T$(TARGET_DIR)/stm32wb55xx_flash_cm4.ld | LDFLAGS			+= -T$(TARGET_DIR)/stm32wb55xx_flash_cm4.ld | ||||||
| 
 | 
 | ||||||
|  | # Version generation
 | ||||||
|  | CFLAGS			+= -I../lib/version | ||||||
|  | C_SOURCES		+= ../lib/version/version.c | ||||||
|  | 
 | ||||||
| ASM_SOURCES		+= $(wildcard $(TARGET_DIR)/*.s) | ASM_SOURCES		+= $(wildcard $(TARGET_DIR)/*.s) | ||||||
| C_SOURCES		+= $(wildcard $(TARGET_DIR)/*.c) | C_SOURCES		+= $(wildcard $(TARGET_DIR)/*.c) | ||||||
| CPP_SOURCES		+= $(wildcard $(TARGET_DIR)/*.cpp) | CPP_SOURCES		+= $(wildcard $(TARGET_DIR)/*.cpp) | ||||||
|  | |||||||
| @ -55,7 +55,7 @@ _Min_Stack_Size = 0x400; /* required amount of stack */ | |||||||
| /* Specify the memory areas */ | /* Specify the memory areas */ | ||||||
| MEMORY | MEMORY | ||||||
| { | { | ||||||
| FLASH (rx)                 : ORIGIN = 0x08000000, LENGTH = 512K | FLASH (rx)                 : ORIGIN = 0x08000000, LENGTH = 32K | ||||||
| RAM1 (xrw)                 : ORIGIN = 0x20000004, LENGTH = 0x2FFFC | RAM1 (xrw)                 : ORIGIN = 0x20000004, LENGTH = 0x2FFFC | ||||||
| RAM_SHARED (xrw)           : ORIGIN = 0x20030000, LENGTH = 10K | RAM_SHARED (xrw)           : ORIGIN = 0x20030000, LENGTH = 10K | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ | |||||||
| #include <stm32wbxx_ll_gpio.h> | #include <stm32wbxx_ll_gpio.h> | ||||||
| #include <stm32wbxx_hal_flash.h> | #include <stm32wbxx_hal_flash.h> | ||||||
| 
 | 
 | ||||||
|  | #include <version.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| 
 | 
 | ||||||
| // Boot request enum
 | // Boot request enum
 | ||||||
| @ -110,6 +111,10 @@ void rtc_init() { | |||||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); |     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void version_save(void) { | ||||||
|  |     LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR1, (uint32_t)version_get()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void usb_wire_reset() { | void usb_wire_reset() { | ||||||
|     LL_GPIO_ResetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN); |     LL_GPIO_ResetOutputPin(BOOT_USB_PORT, BOOT_USB_PIN); | ||||||
|     LL_mDelay(10); |     LL_mDelay(10); | ||||||
| @ -122,6 +127,7 @@ void target_init() { | |||||||
|     api_hal_init(); |     api_hal_init(); | ||||||
|     target_led_control("RGB"); |     target_led_control("RGB"); | ||||||
|     rtc_init(); |     rtc_init(); | ||||||
|  |     version_save(); | ||||||
|     usb_wire_reset(); |     usb_wire_reset(); | ||||||
| 
 | 
 | ||||||
|     // Errata 2.2.9, Flash OPTVERR flag is always set after system reset
 |     // Errata 2.2.9, Flash OPTVERR flag is always set after system reset
 | ||||||
|  | |||||||
| @ -37,6 +37,9 @@ C_SOURCES		+= $(DRIVERS_DIR)/lp5562.c | |||||||
| CFLAGS			+= -I$(TARGET_DIR)/api-hal | CFLAGS			+= -I$(TARGET_DIR)/api-hal | ||||||
| C_SOURCES		+= $(wildcard $(TARGET_DIR)/api-hal/*.c) | C_SOURCES		+= $(wildcard $(TARGET_DIR)/api-hal/*.c) | ||||||
| 
 | 
 | ||||||
|  | # Version generation
 | ||||||
|  | CFLAGS			+= -I../lib/version | ||||||
|  | C_SOURCES		+= ../lib/version/version.c | ||||||
| 
 | 
 | ||||||
| ASM_SOURCES		+= $(wildcard $(TARGET_DIR)/*.s) | ASM_SOURCES		+= $(wildcard $(TARGET_DIR)/*.s) | ||||||
| C_SOURCES		+= $(wildcard $(TARGET_DIR)/*.c) | C_SOURCES		+= $(wildcard $(TARGET_DIR)/*.c) | ||||||
|  | |||||||
| @ -1,12 +1,33 @@ | |||||||
| #include "flipper.h" | #include "flipper.h" | ||||||
| #include <applications.h> | #include <applications.h> | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
|  | #include <version.h> | ||||||
|  | #include <api-hal-version.h> | ||||||
|  | 
 | ||||||
|  | static void flipper_print_version(const Version* version) { | ||||||
|  |     if(version) { | ||||||
|  |         printf("\tVersion:\t%s\r\n", version_get_version(version)); | ||||||
|  |         printf("\tBuild date:\t%s\r\n", version_get_builddate(version)); | ||||||
|  |         printf( | ||||||
|  |             "\tGit Commit:\t%s (%s)\r\n", | ||||||
|  |             version_get_githash(version), | ||||||
|  |             version_get_gitbranchnum(version)); | ||||||
|  |         printf("\tGit Branch:\t%s\r\n", version_get_gitbranch(version)); | ||||||
|  |     } else { | ||||||
|  |         printf("\tNo build info\r\n"); | ||||||
|  |     } | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| void flipper_init() { | void flipper_init() { | ||||||
|     printf("[flipper] Build date:" BUILD_DATE ". " |     const Version* version; | ||||||
|            "Git Commit:" GIT_COMMIT ". " | 
 | ||||||
|            "Git Branch:" GIT_BRANCH ". " |     version = (const Version*)api_hal_version_get_boot_version(); | ||||||
|            "Commit Number:" GIT_BRANCH_NUM "\r\n"); |     printf("Bootloader\r\n"); | ||||||
|  |     flipper_print_version(version); | ||||||
|  | 
 | ||||||
|  |     version = (const Version*)api_hal_version_get_fw_version(); | ||||||
|  |     printf("Firmware\r\n"); | ||||||
|  |     flipper_print_version(version); | ||||||
| 
 | 
 | ||||||
|     printf("[flipper] starting services\r\n"); |     printf("[flipper] starting services\r\n"); | ||||||
| 
 | 
 | ||||||
| @ -23,4 +44,4 @@ void flipper_init() { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     printf("[flipper] services startup complete\r\n"); |     printf("[flipper] services startup complete\r\n"); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  | #include <stdint.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
|  | #include <version.h> | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| extern "C" { | extern "C" { | ||||||
| @ -29,6 +30,20 @@ const uint32_t api_hal_version_get_hw_timestamp(); | |||||||
| /** Get pointer to target name */ | /** Get pointer to target name */ | ||||||
| const char * api_hal_version_get_name_ptr(); | const char * api_hal_version_get_name_ptr(); | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * Get address of version structure of bootloader, stored in chip flash. | ||||||
|  |  * | ||||||
|  |  * @return Address of boot version structure. | ||||||
|  |  */ | ||||||
|  | const struct Version* api_hal_version_get_boot_version(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Get address of version structure of firmware. | ||||||
|  |  * | ||||||
|  |  * @return Address of firmware version structure. | ||||||
|  |  */ | ||||||
|  | const struct Version* api_hal_version_get_fw_version(void); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -10,4 +10,5 @@ void api_hal_boot_set_mode(ApiHalBootMode mode) { | |||||||
|     } else if (mode == ApiHalBootModeDFU) { |     } else if (mode == ApiHalBootModeDFU) { | ||||||
|         LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU); |         LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include <api-hal-version.h> | #include <api-hal-version.h> | ||||||
| #include <stm32wbxx.h> | #include <stm32wbxx.h> | ||||||
|  | #include <stm32wbxx_ll_rtc.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t version; |     uint8_t version; | ||||||
| @ -38,3 +39,17 @@ const char * api_hal_version_get_name_ptr() { | |||||||
|     char * name = ((ApiHalVersionOTP*)OTP_AREA_BASE)->name; |     char * name = ((ApiHalVersionOTP*)OTP_AREA_BASE)->name; | ||||||
|     return *name == 0xFFU ? NULL : name;  |     return *name == 0xFFU ? NULL : name;  | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | const struct Version* api_hal_version_get_fw_version(void) { | ||||||
|  |     return version_get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const struct Version* api_hal_version_get_boot_version(void) { | ||||||
|  | #ifdef NO_BOOTLOADER | ||||||
|  |     return 0; | ||||||
|  | #else | ||||||
|  |     /* Backup register which points to structure in flash memory */ | ||||||
|  |     return (const struct Version*) LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR1); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -10,4 +10,5 @@ void api_hal_boot_set_mode(ApiHalBootMode mode) { | |||||||
|     } else if (mode == ApiHalBootModeDFU) { |     } else if (mode == ApiHalBootModeDFU) { | ||||||
|         LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU); |         LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -1,5 +1,6 @@ | |||||||
| #include <api-hal-version.h> | #include <api-hal-version.h> | ||||||
| #include <stm32wbxx.h> | #include <stm32wbxx.h> | ||||||
|  | #include <stm32wbxx_ll_rtc.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t version; |     uint8_t version; | ||||||
| @ -38,3 +39,17 @@ const char * api_hal_version_get_name_ptr() { | |||||||
|     char * name = ((ApiHalVersionOTP*)OTP_AREA_BASE)->name; |     char * name = ((ApiHalVersionOTP*)OTP_AREA_BASE)->name; | ||||||
|     return *name == 0xFFU ? NULL : name;  |     return *name == 0xFFU ? NULL : name;  | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | const struct Version* api_hal_version_get_fw_version(void) { | ||||||
|  |     return version_get(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const struct Version* api_hal_version_get_boot_version(void) { | ||||||
|  | #ifdef NO_BOOTLOADER | ||||||
|  |     return 0; | ||||||
|  | #else | ||||||
|  |     /* Backup register which points to structure in flash memory */ | ||||||
|  |     return (const struct Version*) LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR1); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | |||||||
| @ -82,3 +82,8 @@ CFLAGS			+= -I$(LIB_DIR)/common-api | |||||||
| # drivers
 | # drivers
 | ||||||
| CFLAGS			+= -I$(LIB_DIR)/drivers | CFLAGS			+= -I$(LIB_DIR)/drivers | ||||||
| C_SOURCES		+= $(wildcard $(LIB_DIR)/drivers/*.c) | C_SOURCES		+= $(wildcard $(LIB_DIR)/drivers/*.c) | ||||||
|  | 
 | ||||||
|  | #version
 | ||||||
|  | CFLAGS			+= -I$(LIB_DIR)/version | ||||||
|  | C_SOURCES		+= $(LIB_DIR)/version/version.c | ||||||
|  | 
 | ||||||
|  | |||||||
							
								
								
									
										50
									
								
								lib/version/version.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								lib/version/version.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | #include "version.h" | ||||||
|  | 
 | ||||||
|  | struct Version { | ||||||
|  |     const char*  git_hash; | ||||||
|  |     const char*  git_branch; | ||||||
|  |     const char*  git_branch_num; | ||||||
|  |     const char*  build_date; | ||||||
|  |     const char*  version; | ||||||
|  |     const char*  target; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /* version of current running firmware (bootloader/flipper) */ | ||||||
|  | static const Version version = { | ||||||
|  |     .git_hash       = GIT_COMMIT, | ||||||
|  |     .git_branch     = GIT_BRANCH, | ||||||
|  |     .git_branch_num = GIT_BRANCH_NUM, | ||||||
|  |     .build_date     = BUILD_DATE, | ||||||
|  |     .version        = VERSION, | ||||||
|  |     .target         = TARGET, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const Version* version_get(void) { | ||||||
|  |     return &version; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* version_get_githash(const Version* v) { | ||||||
|  |     return v ? v->git_hash : version.git_hash; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* version_get_gitbranch(const Version* v) { | ||||||
|  |     return v ? v->git_branch : version.git_branch; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* version_get_gitbranchnum(const Version* v) { | ||||||
|  |     return v ? v->git_branch_num : version.git_branch_num; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* version_get_builddate(const Version* v) { | ||||||
|  |     return v ? v->build_date : version.build_date; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* version_get_version(const Version* v) { | ||||||
|  |     return v ? v->version : version.version; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const char* version_get_target(const Version* v) { | ||||||
|  |     return v ? v->target : version.target; | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										73
									
								
								lib/version/version.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								lib/version/version.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | typedef struct Version Version; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets current running firmware version handle. | ||||||
|  |  * You can store it somewhere. But if you want to retrieve data, | ||||||
|  |  * you have to use 'version_*_get()' set of functions. | ||||||
|  |  * Also, 'version_*_get()' imply to use this | ||||||
|  |  * handle if no handle (NULL_PTR) provided. | ||||||
|  |  * | ||||||
|  |  * @return Handle to version data. | ||||||
|  |  */ | ||||||
|  | const Version* version_get(void); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets git hash of build commit. | ||||||
|  |  * | ||||||
|  |  * @param   v - ptr to version handle. If zero - gets current running fw info. | ||||||
|  |  * @return  git hash | ||||||
|  |  */ | ||||||
|  | const char* version_get_githash(const Version* v); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets git branch of build commit. | ||||||
|  |  * | ||||||
|  |  * @param   v - ptr to version handle. If zero - gets current running fw info. | ||||||
|  |  * @return  git branch | ||||||
|  |  */ | ||||||
|  | const char* version_get_gitbranch(const Version* v); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets git number of build commit. | ||||||
|  |  * | ||||||
|  |  * @param   v - ptr to version handle. If zero - gets current running fw info. | ||||||
|  |  * @return  number of commit | ||||||
|  |  */ | ||||||
|  | const char* version_get_gitbranchnum(const Version* v); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets build date. | ||||||
|  |  * | ||||||
|  |  * @param   v - ptr to version handle. If zero - gets current running fw info. | ||||||
|  |  * @return  build date | ||||||
|  |  */ | ||||||
|  | const char* version_get_builddate(const Version* v); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets build version. | ||||||
|  |  * Build version is last tag in git history. | ||||||
|  |  * | ||||||
|  |  * @param   v - ptr to version handle. If zero - gets current running fw info. | ||||||
|  |  * @return  build date | ||||||
|  |  */ | ||||||
|  | const char* version_get_version(const Version* v); | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * Gets firmware target. | ||||||
|  |  * Build version is last tag for build commit. | ||||||
|  |  * | ||||||
|  |  * @param   v - ptr to version handle. If zero - gets current running fw info. | ||||||
|  |  * @return  build date | ||||||
|  |  */ | ||||||
|  | const char* version_get_target(const Version* v); | ||||||
|  | 
 | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| @ -2,6 +2,8 @@ GIT_COMMIT		= $(shell git describe --always  --exclude '*' || echo 'unknown') | |||||||
| GIT_BRANCH		= $(shell git rev-parse --abbrev-ref HEAD || echo 'unknown') | GIT_BRANCH		= $(shell git rev-parse --abbrev-ref HEAD || echo 'unknown') | ||||||
| GIT_BRANCH_NUM	= $(shell git rev-list --count $(GIT_BRANCH) || echo 'nan') | GIT_BRANCH_NUM	= $(shell git rev-list --count $(GIT_BRANCH) || echo 'nan') | ||||||
| BUILD_DATE		= $(shell date '+%d-%m-%Y' || echo 'unknown') | BUILD_DATE		= $(shell date '+%d-%m-%Y' || echo 'unknown') | ||||||
|  | VERSION			= $(shell git describe --tags --abbrev=0 || echo 'unknown') | ||||||
| 
 | 
 | ||||||
| CFLAGS			+= -DGIT_COMMIT="\"$(GIT_COMMIT)\"" -DGIT_BRANCH="\"$(GIT_BRANCH)\"" -DGIT_BRANCH_NUM="\"$(GIT_BRANCH_NUM)\"" | CFLAGS			+= -DGIT_COMMIT="\"$(GIT_COMMIT)\"" -DGIT_BRANCH="\"$(GIT_BRANCH)\"" -DGIT_BRANCH_NUM="\"$(GIT_BRANCH_NUM)\"" | ||||||
| CFLAGS			+= -DBUILD_DATE="\"$(BUILD_DATE)\"" -DTARGET="\"$(TARGET)\"" | CFLAGS			+= -DBUILD_DATE="\"$(BUILD_DATE)\"" -DTARGET="\"$(TARGET)\"" -DVERSION="\"$(VERSION)\"" | ||||||
|  | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Albert Kharisov
						Albert Kharisov