So verbinden Sie den Inhalt von Dateien zur Verwendung in C / C ++ - Code

Hallo Chabrowiten!





Dies ist mein erster Artikel und ich habe etwas zu teilen. Vielleicht ist mein Fahrrad nicht neu und jeder verwendet diese Methode, aber als ich einmal nach einer Lösung suchte, konnte ich sie nicht sofort finden.





Worüber reden wir?

Die Aufgabe bestand darin, Dateien einzuschließen: HTML , JS , CSS ; ohne spezielle Ausbildung. Es ist auch unpraktisch, Binärdateien (z. B. Bilder ) durch Konvertieren in HEX zu verbinden . Da ich nicht in HEX konvertieren oder in Zeilen aufteilen wollte, suchte ich nach einer Möglichkeit, die Datei mit dem Programmadressraum zu verbinden .





Wie es normalerweise aussieht

Beispiel mit Linienaufteilung:





const char text[] =
    "<html>"            "\r\n"
    "<body>Text</body>" "\r\n"
    "</html>";
      
      



Beispiel mit HEX (besser geeignet für Binärdaten):





const char text[] =
    {
        0x3C, 0x68, 0x74, 0x6D, 0x6C, 0x3E, 0x0A, 0x3C,
        0x62, 0x6F, 0x64, 0x79, 0x3E, 0x54, 0x65, 0x78,
        0x74, 0x3C, 0x2F, 0x62, 0x6F, 0x64, 0x79, 0x3E,
        0x0A, 0x3C, 0x2F, 0x68, 0x74, 0x6D, 0x6C, 0x3E,
        0
    };
      
      



Ich habe das sogar gesehen:





#define TEXT "<html>\r\n<body>Text</body>\r\n</html>"
const char text[] = TEXT;
      
      



#define .h Python. , \ . .





, , , :





extern const char text[];
      
      



, Assembler.





Arduino IDE

text.S, text.htm.





text.htm:





<html>
<body>Text</body>
</html>
      
      



text.S:





.global text
.section .rodata.myfiles
text:
    .incbin "text.htm"
    .byte 0
      
      



\0 , .





:





extern const char text[] PROGMEM;

void setup()
{
    Serial.begin(115200);
    Serial.println(text);
}

void loop() { }
      
      



, :





, - , .





AVR8, ESP8266 . , Flash 32 32 . , , :





.global text
.section .rodata.myfiles

.align 4
text:
    .incbin "text.htm"
    .byte 0
      
      



: .irom.text, .rodata.





STM32 32 , .





? , . :





.global text, text_size

.section .rodata.myfiles

text:
    .incbin "text.htm"
    text_end:
    .byte 0

text_size:
	.word (text_end - text)
      
      



:





extern const char text[] PROGMEM;
extern const uint16_t text_size PROGMEM;
      
      



, :





.macro addFile name file
    .global \name, \name\()_size
//  .align 4
    \name:
        .incbin "\file"
        \name\()_end:
        .byte 0
//  .align 4
    \name\()_size:
        .word (\name\()_end - \name)
.endm

.section .rodata.myfiles

addFile text1   1.txt
addFile text2   2.txt
addFile text3   3.txt
      
      



:





#define ADD_FILE(name) \
    extern const char name[] PROGMEM; \
    extern const uint16_t name##_size PROGMEM;

ADD_FILE(text1);
ADD_FILE(text2);
ADD_FILE(text3);

void setup()
{
    Serial.begin(115200);
    Serial.println(text1);
    Serial.println(text1_size);
    Serial.println(text2);
    Serial.println(text2_size);
    Serial.println(text3);
    Serial.println(text3_size);
}

void loop() { }
      
      



:





, .





, GNU toolchain

, Arduino. Arduino toolchain Atmel.





Makefile - .





STM32, . WEB- LWIP / HTTPD.





version.sh:





#!/bin/bash
# Version generator
# running script from pre-build

MAJOR=1
MINOR=0

cd "$(dirname $0)" &>/dev/null

FILE_VERSION="version.txt"
FILE_ASM="version.S"

BUILD=$(head -n1 "$FILE_VERSION" 2>/dev/null)
if [ -z "$BUILD" ]; then
	BUILD=0
else
	BUILD=$(expr $BUILD + 1)
fi
echo -n "$BUILD" >"$FILE_VERSION"

cat <<EOF >"$FILE_ASM"
/**
* no editing, automatically generated from version.sh
*/

.section .rodata
.global __version_major
.global __version_minor
.global __version_build
__version_major: .word $MAJOR
__version_minor: .word $MINOR
__version_build: .word $BUILD
.end
EOF

cd - &>/dev/null
exit 0
      
      



version.S version.txt .





Makefile pre-build:





#######################################
# pre-build script
#######################################
pre-build:
	bash version.sh
      
      



all pre-build:





all: pre-build $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
      
      



printf macro.h:





extern const uint16_t __version_major;
extern const uint16_t __version_minor;
extern const uint16_t __version_build;
#define FMT_VER             "%u.%u.%u"
#define FMT_VER_VAL         __version_major, __version_minor, __version_build
      
      



HTTPD LWIP , HTTP. , fsdata.c. fsdata_custom.c, HTTPD_USE_CUSTOM_FSDATA.





fsdata_custom.c:





#include "lwip/apps/fs.h"
#include "lwip/def.h"
#include "fsdata.h"
#include "macro.h"

extern const struct fsdata_file __fs_root;

#define FS_ROOT &__fs_root
      
      



fsdata_make.S:





.macro addData name file mime
	\name\():
	.string "/\file\()"
	\name\()_data:
	.incbin "mime/\mime\().txt"
	.incbin "\file\()"
	\name\()_end:
.endm

.macro addFile name next
	\name\()_file:
	.word \next\()
	.word \name\()
	.word \name\()_data
	.word \name\()_end - \name\()_data
	.word 1
.endm

.section .rodata.fsdata
.global __fs_root

/* Load files */
addData __index_htm         index.htm           html
addData __styles_css        styles.css          css
addData __lib_js            lib.js              js
addData __ui_js             ui.js               js
addData __404_htm           404.htm             404
addData __favicon_ico       img/favicon.ico     ico
addData __logo_png          img/logo.png        png

/* FSDATA Table */
addFile __logo_png          0
addFile __favicon_ico       __logo_png_file
addFile __404_htm           __favicon_ico_file
addFile __ui_js             __404_htm_file
addFile __lib_js            __ui_js_file
addFile __styles_css        __lib_js_file
__fs_root:
addFile __index_htm         __styles_css_file

.end

      
      



, mime.





html.txt:





HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Connection: close


      
      



404.txt:





HTTP/1.1 404 Not found
Content-Type: text/plain; charset=UTF-8
Connection: close


      
      



Beachten Sie die leere Zeile, die in der HTTP- Spezifikation erforderlich ist , um das Ende des Headers zu markieren. Jede Zeile muss mit CRLF (\ r \ n) enden .





PS Der Projektcode stammt aus einer heruntergekommenen Truhe, sodass die Implementierung möglicherweise etwas zur Klärung vergisst.





Am Ende

Ich habe lange nach etwas Nützlichem in dem Artikel gesucht. Ich hoffe, meine Erfahrung ist nützlich für einen Anfänger und einen Guru.





Vielen Dank für Ihre Aufmerksamkeit, glückliche Entwicklungen!








All Articles