├── LICENSE ├── README.md ├── examples └── incbin-print-self │ └── incbin-print-self.ino ├── incbin.png ├── library.properties └── src ├── README.md ├── UNLICENSE ├── _incbin.h └── incbin.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021, Dale Weiler (https://github.com/graphitemaster) 4 | Copyright (c) 2021, github.com/AlexIII 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # incbin - Include binary and text files in your Arduino project with ease 2 | 3 | 4 | *This is a fork of [this](https://github.com/graphitemaster/incbin) project wrapped as an Arduino library.* 5 | 6 | The library allows to include any file into your Arduino project in a single line without 7 | converting it into c-array or maintaining a file system (such as SPIFFS). 8 | 9 | Easily include wav sound, bmp image, html, js, txt, etc. 10 | 11 | ## IMPORTANT NOTE 12 | 13 | When using this library, 14 | 1. Close **all** Arduino IDE windows, 15 | 2. Re-open your ***.ino file via double-click**. Do NOT do File -> Open... 16 | 17 | See [Limitations](#Limitations) for the explanation. 18 | 19 | 20 | ## How to use 21 | 22 | ```C++ 23 | #include "incbin.h" 24 | 25 | INCTXT(WebPage, "index.html"); // For text (will be NULL-terminated) 26 | INCBIN(Sound, "sound.wav"); // For binary 27 | 28 | void setup() { 29 | Serial.begin(115200); 30 | 31 | Serial.println(gWebPageData); // print content of index.html 32 | Serial.println(); 33 | 34 | Serial.print(F("index.html size: ")); 35 | Serial.println(gWebPageSize); // print size of index.html 36 | 37 | Serial.print(F("sound.wav size: ")); 38 | Serial.println(gSoundSize); // print size of sound.wav 39 | } 40 | ``` 41 | 42 | Macros `INCTXT(NAME, FILE)` and `INCBIN(NAME, FILE)` accept path to the `FILE` 43 | **relative to the project main folder** (where the *.ino file is placed), and 44 | NOT to the source file in which you use these macros. You can use absolute path as well. 45 | 46 | See the [`incbin-print-self.ino`](examples/incbin-print-self/incbin-print-self.ino) example for more. 47 | 48 | 49 | ## How it works 50 | 51 | The library includes the content of the specified file in Flash ROM of the microcontroller. 52 | It means that, 53 | 54 | - the RAM is not wasted; 55 | - the file is included as a constant, its content cannot be changed; 56 | - you cannot work with the file content as with a normal array on AVR-based Arduino, as it's stored in the flash memory (PROGMEM). See [here](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/) on how to read the flash. 57 | 58 | 59 | ## Limitations 60 | 61 | If you encounter a compilation error like this 62 | 63 | ``` 64 | ***PATH***.s: Assembler messages: 65 | ***PATH***.s:16: Error: file not found: ***FILE YOU TRIED TO INCBIN*** 66 | lto-wrapper.exe: fatal error: 67 | ... 68 | ``` 69 | 70 | do the following steps: 71 | 72 | #### Windows Arduino IDE 1.8 users 73 | 1. Close **all** Arduino IDE windows, 74 | 2. Re-open your ***.ino file via double-click**. Do NOT do File -> Open... 75 | 76 | #### [VS Code Arduino](https://marketplace.visualstudio.com/items?itemName=vsciot-vscode.vscode-arduino) extension users (any OS) 77 | 1. Upgrade your extension to v0.4.7 or newer, 78 | 2. Ensure the path in the `INCBIN` or `INCTXT` is **relative to the workspace folder**, and not to the source file. You can also use absolute path. 79 | 80 | #### Windows Arduino IDE 2 Beta, Linux Arduino IDE (any) 81 | No solutions to use relative path. Sorry. Use absolute path instead. Linux users may also use path relative to home. 82 | 83 | ### Ok, but why??? 84 | 85 | The underlying library uses the `.incbin` directive of the inline assembler. The thing is, it accepts the path relative to the current directory in which the compiler is running (and not to the source file). 86 | Arduino IDE *usually* starts the build in the project main directory (in which the *.ino file resides), but it is not guaranteed. Sometimes build can start in another directory and will fail. Re-opening the IDE via double-click on the *.ino file convinces it to start the build in the project's folder (but only in ver. 1.8 under Windows). 87 | 88 | Also, a library example never runs compilation in its own folder, that's why you need to copy it somewhere on the disk, otherwise the compilation will fail. 89 | 90 | **If you have an idea on how to handle this *right* way, please post an issue on the subject.** 91 | 92 | 93 | ## Supported architectures 94 | 95 | Tested with 96 | - AVR-based Arduino: Uno, Nano, Mini Pro, 2560, etc. 97 | - ESP8266 98 | 99 | Should also work with 100 | - ARM-based Arduino 101 | - ESP8285 102 | 103 | 104 | ## License 105 | 106 | MIT 107 | 108 | © [Dale Weiler](https://github.com/graphitemaster) 109 | 110 | © [AlexIII](https://github.com/AlexIII) 111 | 112 | 113 | The original library goes under [UNLICENSE](src/UNLICENSE). 114 | I'm no legal expert, but I think it permits derivative work to have a different license. 115 | If you think it's not, then please post an issue. 116 | -------------------------------------------------------------------------------- /examples/incbin-print-self/incbin-print-self.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * File: incbin-print-self.ino 3 | * Description: incbin Aduino example. Prints out the content of this file to Serial. 4 | * URL: https://github.com/AlexIII/incbin-arduino 5 | * 6 | */ 7 | // !!! IMPORTANT !!! 8 | // !!! This example WON'T COMPILE unless you follow these instructions !!! 9 | /* ----------------------------------------------------------------------------------------------- 10 | * 1. SAVE this example (CTRL+S) to any folder on your disk 11 | * 2. CLOSE ALL Arduino windows 12 | * 3. Re-open the *.ino file you've just saved via DOUBLE-CLICK (DO NOT do File -> Open...) 13 | * ----------------------------------------------------------------------------------------------- 14 | * 15 | * 16 | * - You can use this library in your *.ino project as usual, 17 | * it will compile fine, but you will have to open it via double-click every time. 18 | * - See the github page for detailed explanation of these shenanigans. 19 | * - If you have troubles using this library feel free to open an issue on the github. 20 | * 21 | */ 22 | 23 | #include "incbin.h" 24 | 25 | // Include TEXT file "incbin-print-self.ino" with name `Sketch` 26 | INCTXT(SketchText, "incbin-print-self.ino"); 27 | // This will create global variables: 28 | // const __FlashStringHelper gSketchTextData[]; // NULL-terminated Flash string, pointer to the data 29 | // const __FlashStringHelper *const gSketchTextEnd; // Pointer to the end of the data 30 | // const unsigned int gSketchTextSize; // Size of the data in bytes 31 | 32 | 33 | // Alternatively you can include the file as BINARY data 34 | // -- 35 | // INCBIN(SketchText, "incbin-print-self.ino"); 36 | // -- 37 | // This will create global variables: 38 | // const unsigned char gSketchTextData[]; // Pointer to the data 39 | // const unsigned char *const gSketchTextEnd; // Pointer to the end of the data 40 | // const unsigned int gSketchTextSize; // Size of the data in bytes 41 | 42 | void setup() { 43 | Serial.begin(115200); 44 | 45 | // Print data content 46 | Serial.println(F("----------------------------------")); 47 | Serial.println(gSketchTextData); 48 | Serial.println(F("----------------------------------")); 49 | 50 | // Print data size 51 | Serial.print(F("Sketch file size: ")); 52 | Serial.println(gSketchTextSize); 53 | 54 | 55 | /* Alternatively, read the data from ROM byte-by-byte */ 56 | // PGM_P p = reinterpret_cast(gSketchTextData); 57 | // for(int i = 0; i < gSketchTextSize; ++i) { 58 | // unsigned char c = pgm_read_byte(p++); 59 | // Serial.write(c); 60 | // } 61 | // Serial.println(); 62 | 63 | } 64 | 65 | void loop() {} 66 | -------------------------------------------------------------------------------- /incbin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlexIII/incbin-arduino/d7ee21d2f3e695d959fc9533b07a84c69b99e0be/incbin.png -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=incbin 2 | version=0.1.2 3 | author=Dale Weiler, AlexIII 4 | maintainer=AlexIII 5 | sentence=Include binary and text files in your Arduino project with ease. 6 | paragraph=The library allows to include any file into your Arduino project in a single line without converting it into c-array or maintaining a file system (such as SPIFFS). Easily include wav sound, bmp image, html, js, txt, etc. 7 | category=Data Storage 8 | url=https://github.com/AlexIII/incbin-arduino 9 | architectures=* 10 | includes=incbin.h -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # incbin 2 | 3 | Include binary files in your C/C++ applications with ease 4 | 5 | ## Example 6 | 7 | ``` c 8 | #include "incbin.h" 9 | 10 | INCBIN(Icon, "icon.png"); 11 | 12 | // This translation unit now has three symbols 13 | // const unsigned char gIconData[]; 14 | // const unsigned char *const gIconEnd; // a marker to the end, take the address to get the ending pointer 15 | // const unsigned int gIconSize; 16 | 17 | // Reference in other translation units like this 18 | INCBIN_EXTERN(Icon); 19 | 20 | // This translation unit now has three extern symbols 21 | // Use `extern "C"` in case of writing C++ code 22 | // extern const unsigned char gIconData[]; 23 | // extern const unsigned char *const gIconEnd; // a marker to the end, take the address to get the ending pointer 24 | // extern const unsigned int gIconSize; 25 | ``` 26 | 27 | ## Portability 28 | 29 | Known to work on the following compilers 30 | 31 | * GCC 32 | * Clang 33 | * PathScale 34 | * Intel 35 | * Solaris & Sun Studio 36 | * Green Hills 37 | * SNC (ProDG) 38 | * Diab C++ (WindRiver) 39 | * XCode 40 | * ArmCC 41 | * RealView 42 | * ImageCraft 43 | * Stratus VOS C 44 | * TinyCC 45 | * cparser & libfirm 46 | * LCC 47 | * MSVC _See MSVC below_ 48 | 49 | If your compiler is not listed, as long as it supports GCC inline assembler, this 50 | should work. 51 | 52 | ## MISRA 53 | INCBIN can be used in MISRA C setting. However it should be independently checked 54 | due to its use of inline assembly to achieve what it does. Independent verification 55 | of the header has been done several times based on commit: 7e327a28ba5467c4202ec37874beca7084e4b08c 56 | 57 | ## Alignment 58 | 59 | The data included by this tool will be aligned on the architectures word boundary 60 | unless some variant of SIMD is detected, then it's aligned on a byte boundary that 61 | respects SIMD convention just incase your binary data may be used in vectorized 62 | code. The table of the alignments for SIMD this header recognizes is as follows: 63 | 64 | | SIMD | Alignment | 65 | |-----------------------------------------|-----------| 66 | | SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2 | 16 | 67 | | Neon | 16 | 68 | | AVX, AVX2 | 32 | 69 | | AVX512 | 64 | 70 | 71 | ## Prefix 72 | By default, `incbin.h` emits symbols with a `g` prefix. This can be adjusted by 73 | defining `INCBIN_PREFIX` before including `incbin.h` with a desired prefix. For 74 | instance 75 | 76 | ``` c 77 | #define INCBIN_PREFIX g_ 78 | #include "incbin.h" 79 | INCBIN(test, "test.txt"); 80 | 81 | // This translation unit now has three symbols 82 | // const unsigned char g_testData[]; 83 | // const unsigned char *const g_testEnd; 84 | // const unsigned int g_testSize; 85 | ``` 86 | 87 | You can also choose to have no prefix by defining the prefix with nothing, for example: 88 | 89 | ``` c 90 | #define INCBIN_PREFIX 91 | #include "incbin.h" 92 | INCBIN(test, "test.txt"); 93 | 94 | // This translation unit now has three symbols 95 | // const unsigned char testData[]; 96 | // const unsigned char *const testEnd; 97 | // const unsigned int testSize; 98 | ``` 99 | 100 | ## Style 101 | By default, `incbin.h` emits symbols with `CamelCase` style. This can be adjusted 102 | by defining `INCBIN_STYLE` before including `incbin.h` to change the style. There 103 | are two possible styles to choose from 104 | 105 | * INCBIN_STYLE_CAMEL (CamelCase) 106 | * INCBIN_STYLE_SNAKE (snake_case) 107 | 108 | For instance: 109 | 110 | ``` c 111 | #define INCBIN_STYLE INCBIN_STYLE_SNAKE 112 | #include "incbin.h" 113 | INCBIN(test, "test.txt"); 114 | 115 | // This translation unit now has three symbols 116 | // const unsigned char gtest_data[]; 117 | // const unsigned char *const gtest_end; 118 | // const unsigned int gtest_size; 119 | ``` 120 | 121 | Combining both the style and prefix allows for you to adjust `incbin.h` to suite 122 | your existing style and practices. 123 | 124 | ## Overriding Linker Output section 125 | By default, `incbin.h` emits into the read-only linker output section used on 126 | the detected platform. If you need to override this for whatever reason, you 127 | can manually specify the linker output section. 128 | 129 | For example, to emit data into program memory for 130 | [esp8266/Arduino](github.com/esp8266/Arduino): 131 | 132 | ``` c 133 | #define INCBIN_OUTPUT_SECTION ".irom.text" 134 | #include "incbin.h" 135 | INCBIN(Foo, "foo.txt"); 136 | // Data is emitted into program memory that never gets copied to RAM 137 | ``` 138 | 139 | ## Explanation 140 | 141 | `INCBIN` is a macro which uses the inline assembler provided by almost all 142 | compilers to include binary files. It achieves this by utilizing the `.incbin` 143 | directive of the inline assembler. It then uses the assembler to calculate the 144 | size of the included binary and exports two global symbols that can be externally 145 | referenced in other translation units which contain the data and size of the 146 | included binary data respectively. 147 | 148 | ## MSVC 149 | 150 | Supporting MSVC is slightly harder as MSVC lacks an inline assembler which can 151 | include data. To support this we ship a tool which can process source files 152 | containing `INCBIN` macro usage and generate an external source file containing 153 | the data of all of them combined. This file is named `data.c` by default. 154 | Just include it into your build and use the `incbin.h` to reference data as 155 | needed. It's suggested you integrate this tool as part of your projects's 156 | pre-build events so that this can be automated. A more comprehensive list of 157 | options for this tool can be viewed by invoking the tool with `-help` 158 | 159 | If you're using a custom prefix, be sure to specify the prefix on the command 160 | line with `-p ` so that everything matches up; similarly, if you're 161 | using a custom style, be sure to specify the style on the command line with 162 | `-S