nRF Connect SDK API 3.4.99
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#include <fw_info_bare.h>
22
30#define OFFSET_CHECK(type, member, value) \
31 BUILD_ASSERT(offsetof(type, member) == value, \
32 #member " has wrong offset")
33
34/* Static asserts to ensure compatibility */
35OFFSET_CHECK(struct fw_info_ext_api, ext_api_len, 12);
36OFFSET_CHECK(struct fw_info_ext_api, ext_api_id, 16);
37OFFSET_CHECK(struct fw_info_ext_api, ext_api_flags, 20);
38OFFSET_CHECK(struct fw_info_ext_api, ext_api_version, 24);
43/* Macro for initializing struct fw_info_ext_api instances in the correct
44 * linker section. Also creates a uint8_t in another section to provide a count of
45 * the number of struct fw_info_ext_api instances.
46 */
47#define EXT_API(ext_api_name, type, name) \
48 Z_GENERIC_SECTION(.ext_apis) __attribute__((used)) \
49 const uint8_t _CONCAT(name, _ext_api_counter) = 0xFF; \
50 BUILD_ASSERT((sizeof(type) % 4) == 0, \
51 "Size of EXT_API " #type " is not word-aligned"); \
52 struct __packed _CONCAT(name, _t) \
53 { \
54 struct fw_info_ext_api header; \
55 type ext_api; \
56 }; \
57 Z_GENERIC_SECTION(.firmware_info.1) __attribute__((used)) \
58 const struct _CONCAT(name, _t) name = { \
59 .header = {\
60 .magic = {EXT_API_MAGIC}, \
61 .ext_api_id = CONFIG_ ## ext_api_name ## _EXT_API_ID, \
62 .ext_api_flags = CONFIG_ ## ext_api_name ## _EXT_API_FLAGS, \
63 .ext_api_version = CONFIG_ ## ext_api_name ## _EXT_API_VER, \
64 .ext_api_len = sizeof(struct __packed _CONCAT(name, _t)), \
65 }, \
66 .ext_api
67
68
69
73/* Static asserts to ensure compatibility */
74OFFSET_CHECK(struct fw_info_ext_api_request, request, 0);
75OFFSET_CHECK(struct fw_info_ext_api_request, ext_api_max_version, 28);
76OFFSET_CHECK(struct fw_info_ext_api_request, required, 32);
77OFFSET_CHECK(struct fw_info_ext_api_request, ext_api, 36);
81/* Decorator for struct fw_info_ext_api_request instances to place them in the
82 * correct linker section. Also creates a uint8_t in another section to provide a
83 * count of the number of struct fw_info_ext_api instances.
84 */
85#define EXT_API_REQ(name, req, type, var_name) \
86 Z_GENERIC_SECTION(.ext_apis_req) \
87 const uint8_t _CONCAT(var_name, _ext_api_req_counter) = 0xFF; \
88 __noinit const struct __packed \
89 { \
90 struct fw_info_ext_api header; \
91 type ext_api; \
92 } *var_name; \
93 Z_GENERIC_SECTION(.firmware_info.2) \
94 __attribute__((used)) \
95 const struct fw_info_ext_api_request _CONCAT(var_name, _req) = \
96 { \
97 .request = {\
98 .magic = {EXT_API_MAGIC}, \
99 .ext_api_id = CONFIG_ ## name ## _EXT_API_ID, \
100 .ext_api_flags = CONFIG_ ## name ## _EXT_API_FLAGS, \
101 .ext_api_version = CONFIG_ ## name ## _EXT_API_VER, \
102 .ext_api_len = sizeof(struct fw_info_ext_api_request), \
103 }, \
104 .ext_api_max_version = CONFIG_ ## name ## _EXT_API_MAX_VER, \
105 .required = req, \
106 .ext_api = (void *) &var_name, \
107 }
108
109
113/* Static asserts to ensure compatibility */
114OFFSET_CHECK(struct fw_info, magic, 0);
115OFFSET_CHECK(struct fw_info, total_size, 12);
116OFFSET_CHECK(struct fw_info, size, 16);
117OFFSET_CHECK(struct fw_info, version, 20);
118OFFSET_CHECK(struct fw_info, address, 24);
119OFFSET_CHECK(struct fw_info, boot_address, 28);
120OFFSET_CHECK(struct fw_info, valid, 32);
121OFFSET_CHECK(struct fw_info, reserved, 36);
122OFFSET_CHECK(struct fw_info, ext_api_num, 52);
123OFFSET_CHECK(struct fw_info, ext_api_request_num, 56);
124OFFSET_CHECK(struct fw_info, ext_apis, 60);
125BUILD_ASSERT(sizeof(struct fw_info) == offsetof(struct fw_info, ext_apis),
126 "Size of fw_info must assume ext_apis is empty.");
132/* Find the difference between the start of the current image and the address
133 * from which the firmware info offset is calculated.
134 */
135#if defined(PM_S0_PAD_SIZE) && (PM_ADDRESS == PM_S0_IMAGE_ADDRESS)
136 #define FW_INFO_VECTOR_OFFSET PM_S0_PAD_SIZE
137#elif defined(PM_S1_PAD_SIZE) && (PM_ADDRESS == PM_S1_IMAGE_ADDRESS)
138 #define FW_INFO_VECTOR_OFFSET PM_S1_PAD_SIZE
139#elif defined(PM_MCUBOOT_PAD_SIZE) && \
140 (PM_ADDRESS == PM_MCUBOOT_PRIMARY_APP_ADDRESS)
141 #define FW_INFO_VECTOR_OFFSET PM_MCUBOOT_PAD_SIZE
142#else
143 #define FW_INFO_VECTOR_OFFSET 0
144#endif
145
146
150BUILD_ASSERT(ARRAY_SIZE(fw_info_allowed_offsets) == FW_INFO_OFFSET_COUNT,
151 "Mismatch in the number of allowed offsets.");
155/* Build time check of CONFIG_FW_INFO_OFFSET. */
156#if (FW_INFO_OFFSET_COUNT != 7) \
157 || ((FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET0) && \
158 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET1) && \
159 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET2) && \
160 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET3) && \
161 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET4) && \
162 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET5) && \
163 (FW_INFO_CURRENT_OFFSET) != (FW_INFO_OFFSET6))
164 #error FW_INFO_OFFSET not set to one of the allowed values.
165#endif
166
167
182bool fw_info_ext_api_provide(const struct fw_info *fwinfo, bool provide);
183
194
197#ifdef __cplusplus
198}
199#endif
200
201#endif
static const uint32_t fw_info_allowed_offsets[]
Definition fw_info_bare.h:194
#define FW_INFO_OFFSET_COUNT
Definition fw_info_bare.h:31
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:100
Definition fw_info_bare.h:44
Definition fw_info_bare.h:127