nRF Connect SDK API 0.1.0
Loading...
Searching...
No Matches
fw_info.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5 */
6
7#ifndef FW_INFO_H__
8#define FW_INFO_H__
9
10#ifdef __cplusplus
11extern "C" {
12#endif
13
14#include <zephyr/types.h>
15#include <stddef.h>
16#include <zephyr/toolchain.h>
17#include <zephyr/sys/util.h>
18#include <zephyr/sys/__assert.h>
19#include <zephyr/linker/sections.h>
20#include <string.h>
21#if USE_PARTITION_MANAGER
22#include <pm_config.h>
23#endif
24#include <fw_info_bare.h>
25
33#define OFFSET_CHECK(type, member, value) \
34 BUILD_ASSERT(offsetof(type, member) == value, \
35 #member " has wrong offset")
36
37/* Static asserts to ensure compatibility */
38OFFSET_CHECK(struct fw_info_ext_api, ext_api_len, 12);
39OFFSET_CHECK(struct fw_info_ext_api, ext_api_id, 16);
40OFFSET_CHECK(struct fw_info_ext_api, ext_api_flags, 20);
41OFFSET_CHECK(struct fw_info_ext_api, ext_api_version, 24);
46/* Macro for initializing struct fw_info_ext_api instances in the correct
47 * linker section. Also creates a uint8_t in another section to provide a count of
48 * the number of struct fw_info_ext_api instances.
49 */
50#define EXT_API(ext_api_name, type, name) \
51 Z_GENERIC_SECTION(.ext_apis) \
52 const uint8_t _CONCAT(name, _ext_api_counter) = 0xFF; \
53 BUILD_ASSERT((sizeof(type) % 4) == 0, \
54 "Size of EXT_API " #type " is not word-aligned"); \
55 struct __packed _CONCAT(name, _t) \
56 { \
57 struct fw_info_ext_api header; \
58 type ext_api; \
59 }; \
60 Z_GENERIC_SECTION(.firmware_info.1) __attribute__((used)) \
61 const struct _CONCAT(name, _t) name = { \
62 .header = {\
63 .magic = {EXT_API_MAGIC}, \
64 .ext_api_id = CONFIG_ ## ext_api_name ## _EXT_API_ID, \
65 .ext_api_flags = CONFIG_ ## ext_api_name ## _EXT_API_FLAGS, \
66 .ext_api_version = CONFIG_ ## ext_api_name ## _EXT_API_VER, \
67 .ext_api_len = sizeof(struct __packed _CONCAT(name, _t)), \
68 }, \
69 .ext_api
70
71
72
76/* Static asserts to ensure compatibility */
77OFFSET_CHECK(struct fw_info_ext_api_request, request, 0);
78OFFSET_CHECK(struct fw_info_ext_api_request, ext_api_max_version, 28);
79OFFSET_CHECK(struct fw_info_ext_api_request, required, 32);
80OFFSET_CHECK(struct fw_info_ext_api_request, ext_api, 36);
84/* Decorator for struct fw_info_ext_api_request instances to place them in the
85 * correct linker section. Also creates a uint8_t in another section to provide a
86 * count of the number of struct fw_info_ext_api instances.
87 */
88#define EXT_API_REQ(name, req, type, var_name) \
89 Z_GENERIC_SECTION(.ext_apis_req) \
90 const uint8_t _CONCAT(var_name, _ext_api_req_counter) = 0xFF; \
91 __noinit const struct __packed \
92 { \
93 struct fw_info_ext_api header; \
94 type ext_api; \
95 } *var_name; \
96 Z_GENERIC_SECTION(.firmware_info.2) \
97 __attribute__((used)) \
98 const struct fw_info_ext_api_request _CONCAT(var_name, _req) = \
99 { \
100 .request = {\
101 .magic = {EXT_API_MAGIC}, \
102 .ext_api_id = CONFIG_ ## name ## _EXT_API_ID, \
103 .ext_api_flags = CONFIG_ ## name ## _EXT_API_FLAGS, \
104 .ext_api_version = CONFIG_ ## name ## _EXT_API_VER, \
105 .ext_api_len = sizeof(struct fw_info_ext_api_request), \
106 }, \
107 .ext_api_max_version = CONFIG_ ## name ## _EXT_API_MAX_VER, \
108 .required = req, \
109 .ext_api = (void *) &var_name, \
110 }
111
112
116/* Static asserts to ensure compatibility */
117OFFSET_CHECK(struct fw_info, magic, 0);
118OFFSET_CHECK(struct fw_info, total_size, 12);
119OFFSET_CHECK(struct fw_info, size, 16);
120OFFSET_CHECK(struct fw_info, version, 20);
121OFFSET_CHECK(struct fw_info, address, 24);
122OFFSET_CHECK(struct fw_info, boot_address, 28);
123OFFSET_CHECK(struct fw_info, valid, 32);
124OFFSET_CHECK(struct fw_info, reserved, 36);
125OFFSET_CHECK(struct fw_info, ext_api_num, 52);
126OFFSET_CHECK(struct fw_info, ext_api_request_num, 56);
127OFFSET_CHECK(struct fw_info, ext_apis, 60);
128BUILD_ASSERT(sizeof(struct fw_info) == offsetof(struct fw_info, ext_apis),
129 "Size of fw_info must assume ext_apis is empty.");
135/* Find the difference between the start of the current image and the address
136 * from which the firmware info offset is calculated.
137 */
138#if defined(PM_S0_PAD_SIZE) && (PM_ADDRESS == PM_S0_IMAGE_ADDRESS)
139 #define FW_INFO_VECTOR_OFFSET PM_S0_PAD_SIZE
140#elif defined(PM_S1_PAD_SIZE) && (PM_ADDRESS == PM_S1_IMAGE_ADDRESS)
141 #define FW_INFO_VECTOR_OFFSET PM_S1_PAD_SIZE
142#elif defined(PM_MCUBOOT_PAD_SIZE) && \
143 (PM_ADDRESS == PM_MCUBOOT_PRIMARY_APP_ADDRESS)
144 #define FW_INFO_VECTOR_OFFSET PM_MCUBOOT_PAD_SIZE
145#else
146 #define FW_INFO_VECTOR_OFFSET 0
147#endif
148
149
153BUILD_ASSERT(ARRAY_SIZE(fw_info_allowed_offsets) == FW_INFO_OFFSET_COUNT,
154 "Mismatch in the number of allowed offsets.");
158/* Build time check of CONFIG_FW_INFO_OFFSET. */
159#if (FW_INFO_OFFSET_COUNT != 5) \
160 || ((FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET0) && \
161 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET1) && \
162 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET2) && \
163 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET3) && \
164 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET4))
165 #error FW_INFO_OFFSET not set to one of the allowed values.
166#endif
167
168
183bool fw_info_ext_api_provide(const struct fw_info *fwinfo, bool provide);
184
195
198#ifdef __cplusplus
199}
200#endif
201
202#endif
static const uint32_t fw_info_allowed_offsets[]
Definition: fw_info_bare.h:192
#define FW_INFO_OFFSET_COUNT
Definition: fw_info_bare.h:29
bool fw_info_ext_api_provide(const struct fw_info *fwinfo, bool provide)
void fw_info_invalidate(const struct fw_info *fw_info)
Definition: fw_info_bare.h:98
Definition: fw_info_bare.h:42
Definition: fw_info_bare.h:125