1 /* 2 * Copyright (c) 2023 Yonatan Schachter 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ 8 #define ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif /* __cplusplus */ 13 14 /* 15 * Corresponds to the definitions in scripts/west_commands/bindesc.py. 16 * Do not change without syncing the definitions in both files! 17 */ 18 #define BINDESC_MAGIC 0xb9863e5a7ea46046 19 #define BINDESC_ALIGNMENT 4 20 #define BINDESC_TYPE_UINT 0x0 21 #define BINDESC_TYPE_STR 0x1 22 #define BINDESC_TYPE_BYTES 0x2 23 #define BINDESC_TYPE_DESCRIPTORS_END 0xf 24 25 /** 26 * @brief Binary Descriptor Definition 27 * @defgroup bindesc_define Bindesc Define 28 * @{ 29 */ 30 31 /* 32 * Corresponds to the definitions in scripts/west_commands/bindesc.py. 33 * Do not change without syncing the definitions in both files! 34 */ 35 36 /** The app version string such as "1.2.3" */ 37 #define BINDESC_ID_APP_VERSION_STRING 0x800 38 39 /** The app version major such as 1 */ 40 #define BINDESC_ID_APP_VERSION_MAJOR 0x801 41 42 /** The app version minor such as 2 */ 43 #define BINDESC_ID_APP_VERSION_MINOR 0x802 44 45 /** The app version patchlevel such as 3 */ 46 #define BINDESC_ID_APP_VERSION_PATCHLEVEL 0x803 47 48 /** The app version number such as 0x10203 */ 49 #define BINDESC_ID_APP_VERSION_NUMBER 0x804 50 51 /** The kernel version string such as "3.4.0" */ 52 #define BINDESC_ID_KERNEL_VERSION_STRING 0x900 53 54 /** The kernel version major such as 3 */ 55 #define BINDESC_ID_KERNEL_VERSION_MAJOR 0x901 56 57 /** The kernel version minor such as 4 */ 58 #define BINDESC_ID_KERNEL_VERSION_MINOR 0x902 59 60 /** The kernel version patchlevel such as 0 */ 61 #define BINDESC_ID_KERNEL_VERSION_PATCHLEVEL 0x903 62 63 /** The kernel version number such as 0x30400 */ 64 #define BINDESC_ID_KERNEL_VERSION_NUMBER 0x904 65 66 /** The year the image was compiled in */ 67 #define BINDESC_ID_BUILD_TIME_YEAR 0xa00 68 69 /** The month of the year the image was compiled in */ 70 #define BINDESC_ID_BUILD_TIME_MONTH 0xa01 71 72 /** The day of the month the image was compiled in */ 73 #define BINDESC_ID_BUILD_TIME_DAY 0xa02 74 75 /** The hour of the day the image was compiled in */ 76 #define BINDESC_ID_BUILD_TIME_HOUR 0xa03 77 78 /** The minute the image was compiled in */ 79 #define BINDESC_ID_BUILD_TIME_MINUTE 0xa04 80 81 /** The second the image was compiled in */ 82 #define BINDESC_ID_BUILD_TIME_SECOND 0xa05 83 84 /** The UNIX time (seconds since midnight of 1970/01/01) the image was compiled in */ 85 #define BINDESC_ID_BUILD_TIME_UNIX 0xa06 86 87 /** The date and time of compilation such as "2023/02/05 00:07:04" */ 88 #define BINDESC_ID_BUILD_DATE_TIME_STRING 0xa07 89 90 /** The date of compilation such as "2023/02/05" */ 91 #define BINDESC_ID_BUILD_DATE_STRING 0xa08 92 93 /** The time of compilation such as "00:07:04" */ 94 #define BINDESC_ID_BUILD_TIME_STRING 0xa09 95 96 /** The name of the host that compiled the image */ 97 #define BINDESC_ID_HOST_NAME 0xb00 98 99 /** The C compiler name */ 100 #define BINDESC_ID_C_COMPILER_NAME 0xb01 101 102 /** The C compiler version */ 103 #define BINDESC_ID_C_COMPILER_VERSION 0xb02 104 105 /** The C++ compiler name */ 106 #define BINDESC_ID_CXX_COMPILER_NAME 0xb03 107 108 /** The C++ compiler version */ 109 #define BINDESC_ID_CXX_COMPILER_VERSION 0xb04 110 111 #define BINDESC_TAG_DESCRIPTORS_END BINDESC_TAG(DESCRIPTORS_END, 0x0fff) 112 113 /** 114 * @cond INTERNAL_HIDDEN 115 */ 116 117 /* 118 * Utility macro to generate a tag from a type and an ID 119 * 120 * type - Type of the descriptor, UINT, STR or BYTES 121 * id - Unique ID for the descriptor, must fit in 12 bits 122 */ 123 #define BINDESC_TAG(type, id) ((BINDESC_TYPE_##type & 0xf) << 12 | (id & 0x0fff)) 124 125 /** 126 * @endcond 127 */ 128 129 #if !IS_ENABLED(_LINKER) 130 131 #include <zephyr/sys/byteorder.h> 132 133 /** 134 * @cond INTERNAL_HIDDEN 135 */ 136 137 /* 138 * Utility macro to get the name of a bindesc entry 139 */ 140 #define BINDESC_NAME(name) bindesc_entry_##name 141 142 /* Convenience helper for declaring a binary descriptor entry. */ 143 #define __BINDESC_ENTRY_DEFINE(name) \ 144 __aligned(BINDESC_ALIGNMENT) const struct bindesc_entry BINDESC_NAME(name) \ 145 __in_section(_bindesc_entry, static, name) __used __noasan 146 147 /** 148 * @endcond 149 */ 150 151 /** 152 * @brief Define a binary descriptor of type string. 153 * 154 * @details 155 * Define a string that is registered in the binary descriptor header. 156 * The defined string can be accessed using @ref BINDESC_GET_STR 157 * 158 * @note The defined string is not static, so its name must not collide with 159 * any other symbol in the executable. 160 * 161 * @param name Name of the descriptor 162 * @param id Unique ID of the descriptor 163 * @param value A string value for the descriptor 164 */ 165 #define BINDESC_STR_DEFINE(name, id, value) \ 166 __BINDESC_ENTRY_DEFINE(name) = { \ 167 .tag = BINDESC_TAG(STR, id), \ 168 .len = (uint16_t)sizeof(value), \ 169 .data = value, \ 170 } 171 172 /** 173 * @brief Define a binary descriptor of type uint. 174 * 175 * @details 176 * Define an integer that is registered in the binary descriptor header. 177 * The defined integer can be accessed using @ref BINDESC_GET_UINT 178 * 179 * @note The defined integer is not static, so its name must not collide with 180 * any other symbol in the executable. 181 * 182 * @param name Name of the descriptor 183 * @param id Unique ID of the descriptor 184 * @param value An integer value for the descriptor 185 */ 186 #define BINDESC_UINT_DEFINE(name, id, value) \ 187 __BINDESC_ENTRY_DEFINE(name) = { \ 188 .tag = BINDESC_TAG(UINT, id), \ 189 .len = (uint16_t)sizeof(uint32_t), \ 190 .data = sys_uint32_to_array(value), \ 191 } 192 193 /** 194 * @brief Define a binary descriptor of type bytes. 195 * 196 * @details 197 * Define a uint8_t array that is registered in the binary descriptor header. 198 * The defined array can be accessed using @ref BINDESC_GET_BYTES. 199 * The value should be given as an array literal, wrapped in parentheses, for 200 * example: 201 * 202 * BINDESC_BYTES_DEFINE(name, id, ({1, 2, 3, 4})); 203 * 204 * @note The defined array is not static, so its name must not collide with 205 * any other symbol in the executable. 206 * 207 * @param name Name of the descriptor 208 * @param id Unique ID of the descriptor 209 * @param value A uint8_t array as data for the descriptor 210 */ 211 #define BINDESC_BYTES_DEFINE(name, id, value) \ 212 __BINDESC_ENTRY_DEFINE(name) = { \ 213 .tag = BINDESC_TAG(BYTES, id), \ 214 .len = (uint16_t)sizeof((uint8_t [])__DEBRACKET value), \ 215 .data = __DEBRACKET value, \ 216 } 217 218 /** 219 * @brief Get the value of a string binary descriptor 220 * 221 * @details 222 * Get the value of a string binary descriptor, previously defined by 223 * BINDESC_STR_DEFINE. 224 * 225 * @param name Name of the descriptor 226 */ 227 #define BINDESC_GET_STR(name) BINDESC_NAME(name).data 228 229 /** 230 * @brief Get the value of a uint binary descriptor 231 * 232 * @details 233 * Get the value of a uint binary descriptor, previously defined by 234 * BINDESC_UINT_DEFINE. 235 * 236 * @param name Name of the descriptor 237 */ 238 #define BINDESC_GET_UINT(name) *(uint32_t *)&(BINDESC_NAME(name).data) 239 240 /** 241 * @brief Get the value of a bytes binary descriptor 242 * 243 * @details 244 * Get the value of a string binary descriptor, previously defined by 245 * BINDESC_BYTES_DEFINE. The returned value can be accessed as an array: 246 * 247 * for (size_t i = 0; i < BINDESC_GET_SIZE(name); i++) 248 * BINDESC_GET_BYTES(name)[i]; 249 * 250 * @param name Name of the descriptor 251 */ 252 #define BINDESC_GET_BYTES(name) BINDESC_NAME(name).data 253 254 /** 255 * @brief Get the size of a binary descriptor 256 * 257 * @details 258 * Get the size of a binary descriptor. This is particularly useful for 259 * bytes binary descriptors where there's no null terminator. 260 * 261 * @param name Name of the descriptor 262 */ 263 #define BINDESC_GET_SIZE(name) BINDESC_NAME(name).len 264 265 /** 266 * @} 267 */ 268 269 /* 270 * An entry of the binary descriptor header. Each descriptor is 271 * described by one of these entries. 272 */ 273 struct bindesc_entry { 274 /** Tag of the entry */ 275 uint16_t tag; 276 /** Length of the descriptor data */ 277 uint16_t len; 278 /** Value of the entry. This is either an integer or a string */ 279 uint8_t data[]; 280 } __packed; 281 282 /* 283 * We're assuming that `struct bindesc_entry` has a specific layout in 284 * memory, so it's worth making sure that the layout is really what we 285 * think it is. If these assertions fail for your toolchain/platform, 286 * please open a bug report. 287 */ 288 BUILD_ASSERT(offsetof(struct bindesc_entry, tag) == 0, "Incorrect memory layout"); 289 BUILD_ASSERT(offsetof(struct bindesc_entry, len) == 2, "Incorrect memory layout"); 290 BUILD_ASSERT(offsetof(struct bindesc_entry, data) == 4, "Incorrect memory layout"); 291 292 #if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) 293 extern const struct bindesc_entry BINDESC_NAME(kernel_version_string); 294 #endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_STRING) */ 295 296 #if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) 297 extern const struct bindesc_entry BINDESC_NAME(kernel_version_major); 298 #endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MAJOR) */ 299 300 #if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) 301 extern const struct bindesc_entry BINDESC_NAME(kernel_version_minor); 302 #endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_MINOR) */ 303 304 #if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) 305 extern const struct bindesc_entry BINDESC_NAME(kernel_version_patchlevel); 306 #endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_PATCHLEVEL) */ 307 308 #if IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) 309 extern const struct bindesc_entry BINDESC_NAME(kernel_version_number); 310 #endif /* IS_ENABLED(CONFIG_BINDESC_KERNEL_VERSION_NUMBER) */ 311 312 #if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) 313 extern const struct bindesc_entry BINDESC_NAME(app_version_string); 314 #endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_STRING) */ 315 316 #if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) 317 extern const struct bindesc_entry BINDESC_NAME(app_version_major); 318 #endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MAJOR) */ 319 320 #if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) 321 extern const struct bindesc_entry BINDESC_NAME(app_version_minor); 322 #endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_MINOR) */ 323 324 #if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) 325 extern const struct bindesc_entry BINDESC_NAME(app_version_patchlevel); 326 #endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_PATCHLEVEL) */ 327 328 #if IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) 329 extern const struct bindesc_entry BINDESC_NAME(app_version_number); 330 #endif /* IS_ENABLED(CONFIG_BINDESC_APP_VERSION_NUMBER) */ 331 332 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) 333 extern const struct bindesc_entry BINDESC_NAME(build_time_year); 334 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_YEAR) */ 335 336 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) 337 extern const struct bindesc_entry BINDESC_NAME(build_time_month); 338 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MONTH) */ 339 340 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) 341 extern const struct bindesc_entry BINDESC_NAME(build_time_day); 342 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_DAY) */ 343 344 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) 345 extern const struct bindesc_entry BINDESC_NAME(build_time_hour); 346 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_HOUR) */ 347 348 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) 349 extern const struct bindesc_entry BINDESC_NAME(build_time_minute); 350 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_MINUTE) */ 351 352 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) 353 extern const struct bindesc_entry BINDESC_NAME(build_time_second); 354 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_SECOND) */ 355 356 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) 357 extern const struct bindesc_entry BINDESC_NAME(build_time_unix); 358 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_UNIX) */ 359 360 #if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) 361 extern const struct bindesc_entry BINDESC_NAME(build_date_time_string); 362 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_TIME_STRING) */ 363 364 #if IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) 365 extern const struct bindesc_entry BINDESC_NAME(build_date_string); 366 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_DATE_STRING) */ 367 368 #if IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) 369 extern const struct bindesc_entry BINDESC_NAME(build_time_string); 370 #endif /* IS_ENABLED(CONFIG_BINDESC_BUILD_TIME_STRING) */ 371 372 #if IS_ENABLED(CONFIG_BINDESC_HOST_NAME) 373 extern const struct bindesc_entry BINDESC_NAME(host_name); 374 #endif /* IS_ENABLED(CONFIG_BINDESC_HOST_NAME) */ 375 376 #if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) 377 extern const struct bindesc_entry BINDESC_NAME(c_compiler_name); 378 #endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_NAME) */ 379 380 #if IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) 381 extern const struct bindesc_entry BINDESC_NAME(c_compiler_version); 382 #endif /* IS_ENABLED(CONFIG_BINDESC_C_COMPILER_VERSION) */ 383 384 #if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) 385 extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_name); 386 #endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_NAME) */ 387 388 #if IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) 389 extern const struct bindesc_entry BINDESC_NAME(cxx_compiler_version); 390 #endif /* IS_ENABLED(CONFIG_BINDESC_CXX_COMPILER_VERSION) */ 391 392 #endif /* !IS_ENABLED(_LINKER) */ 393 394 #ifdef __cplusplus 395 } 396 #endif 397 398 #endif /* ZEPHYR_INCLUDE_ZEPHYR_BINDESC_H_ */ 399