1 /* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _PICO_BINARY_INFO_CODE_H 8 #define _PICO_BINARY_INFO_CODE_H 9 10 #include "pico.h" 11 #include "pico/binary_info/structure.h" 12 13 #if !PICO_NO_BINARY_INFO 14 #define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *name = bi 15 #define __bi_lineno_var_name __CONCAT(__bi_, __LINE__) 16 #define __bi_ptr_lineno_var_name __CONCAT(__bi_ptr, __LINE__) 17 #define __bi_enclosure_check_lineno_var_name __CONCAT(_error_bi_is_missing_enclosing_decl_,__LINE__) 18 #define __bi_mark_enclosure static const __unused int __bi_enclosure_check_lineno_var_name=0; 19 #if !defined(__GNUC__) || __cplusplus || __GNUC__ >= 8 20 #define __bi_enclosure_check(x) (x + __bi_enclosure_check_lineno_var_name) 21 #else 22 // skip the version check on older GCC non C++, as it doesn't compile.. this is only here to catch the 23 // user accidentally forgetting to enclose the binary item with bi_decl 24 #define __bi_enclosure_check(x) (x) 25 #endif 26 /** 27 * Declare some binary information that will be included if the contain source file/line is compiled into the binary 28 */ 29 #define bi_decl(_decl) __bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.keep.", __used); 30 /** 31 * Declare some binary information that will be included if the function containing the decl is linked into the binary. 32 * The SDK uses --gc-sections, so functions that are never called will be removed by the linker, and any associated 33 * binary information declared this way will also be stripped 34 */ 35 #define bi_decl_if_func_used(_decl) ({__bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(volatile uint8_t *)&__bi_ptr_lineno_var_name;}); 36 37 #define bi_decl_with_attr(_decl, _attr) __bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.keep.", __used); 38 #define bi_decl_if_func_used_with_attr(_decl, _attr) ({__bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(volatile uint8_t *)&__bi_ptr_lineno_var_name;}); 39 #else 40 #define __bi_decl(bi, name, attr) 41 #define bi_decl_with_attr(_decl, _attr) 42 #define bi_decl(_decl) 43 #define bi_decl_if_func_used_with_attr(_decl, _attr) ((void)0); 44 #define bi_decl_if_func_used(_decl) ((void)0); 45 #endif 46 47 #define bi_int(_tag, _id, _value) \ 48 static const struct _binary_info_id_and_int __bi_lineno_var_name = { \ 49 .core = { \ 50 .type = __bi_enclosure_check(BINARY_INFO_TYPE_ID_AND_INT), \ 51 .tag = _tag, \ 52 },\ 53 .id = _id, \ 54 .value = _value \ 55 }; 56 57 #define bi_string(_tag, _id, _value) \ 58 static const struct _binary_info_id_and_string __bi_lineno_var_name = { \ 59 .core = { \ 60 .type = __bi_enclosure_check(BINARY_INFO_TYPE_ID_AND_STRING), \ 61 .tag = _tag, \ 62 },\ 63 .id = _id, \ 64 .value = _value, \ 65 } 66 67 #define bi_block_device(_tag, _name, _address, _size, _extra, _flags) \ 68 static const struct _binary_info_block_device __bi_lineno_var_name = { \ 69 .core = { \ 70 .type = __bi_enclosure_check(BINARY_INFO_TYPE_BLOCK_DEVICE), \ 71 .tag = _tag, \ 72 },\ 73 .name = _name, \ 74 .address = _address, \ 75 .size = _size, \ 76 .extra = _extra, \ 77 .flags = _flags, \ 78 } 79 80 #define __bi_encoded_pins_with_func(_encoding) \ 81 static const struct _binary_info_pins_with_func __bi_lineno_var_name = { \ 82 .core = { \ 83 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PINS_WITH_FUNC), \ 84 .tag = BINARY_INFO_TAG_RASPBERRY_PI, \ 85 },\ 86 .pin_encoding = _encoding \ 87 } 88 89 #define __bi_pins_with_name(_mask, _label) \ 90 static const struct _binary_info_pins_with_name __bi_lineno_var_name = { \ 91 .core = { \ 92 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PINS_WITH_NAME), \ 93 .tag = BINARY_INFO_TAG_RASPBERRY_PI, \ 94 },\ 95 .pin_mask = _mask, \ 96 .label = _label \ 97 } 98 99 #define __bi_named_group(_parent_tag, _parent_id, _group_tag, _group_id, _label, _flags) \ 100 static const struct _binary_info_named_group __bi_lineno_var_name = { \ 101 .core = { \ 102 .type = __bi_enclosure_check(BINARY_INFO_TYPE_NAMED_GROUP), \ 103 .tag = _parent_tag, \ 104 },\ 105 .parent_id = _parent_id, \ 106 .group_tag = _group_tag, \ 107 .flags = _flags, \ 108 .group_id = _group_id, \ 109 .label = _label \ 110 } 111 112 #define bi_binary_end(end) bi_int(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_BINARY_END, end) 113 #define bi_program_name(name) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_NAME, name) 114 #define bi_program_description(description) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_DESCRIPTION, description) 115 #define bi_program_version_string(version_string) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_VERSION_STRING, version_string) 116 #define bi_program_build_date_string(date_string) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_BUILD_DATE_STRING, date_string) 117 #define bi_program_url(url) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_URL, url) 118 // multiple of these may be added 119 #define bi_program_feature(feature) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_FEATURE, feature) 120 #define bi_program_build_attribute(attr) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_BUILD_ATTRIBUTE, attr) 121 #define bi_program_feature_group(tag, id, name) __bi_named_group(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_FEATURE, tag, id, name, 0) 122 #define bi_program_feature_group_with_flags(tag, id, name, flags) __bi_named_group(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_FEATURE, tag, id, name, flags) 123 124 #define bi_1pin_with_func(p0, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p0) << 12)) 125 #define bi_2pins_with_func(p0, p1, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p1) << 17)) 126 #define bi_3pins_with_func(p0, p1, p2, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p2) << 17) | ((p2) << 22)) 127 #define bi_4pins_with_func(p0, p1, p2, p3, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p2) << 17) | ((p3) << 22) | ((p3) << 27)) 128 #define bi_5pins_with_func(p0, p1, p2, p3, p4, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p2) << 17) | ((p3) << 22) | ((p4) << 27)) 129 #define bi_pin_range_with_func(plo, phi, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_RANGE | ((func << 3)) | ((plo) << 7) | ((phi) << 12)) 130 131 #define bi_pin_mask_with_name(pmask, label) __bi_pins_with_name((pmask), (label)) 132 // names are sperated by | ... i.e. "name1|name2|name3" 133 #define bi_pin_mask_with_names(pmask, label) __bi_pins_with_name((pmask), (label)) 134 #define bi_1pin_with_name(p0, name) bi_pin_mask_with_name(1u << (p0), name) 135 #define bi_2pins_with_names(p0, name0, p1, name1) bi_pin_mask_with_names((1u << (p0)) | (1u << (p1)), name0 "|" name1) 136 #define bi_3pins_with_names(p0, name0, p1, name1, p2, name2) bi_pin_mask_with_names((1u << (p0)) | (1u << (p1)) | (1u << (p2)), name0 "|" name1 "|" name2) 137 #define bi_4pins_with_names(p0, name0, p1, name1, p2, name2, p3, name3) bi_pin_mask_with_names((1u << (p0)) | (1u << (p1)) | (1u << (p2)) | (1u << (p3)), name0 "|" name1 "|" name2 "|" name3) 138 139 #endif