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