Initial OTA implementation
parent
5499270903
commit
aff284f570
|
@ -13,6 +13,8 @@
|
||||||
|
|
||||||
#define TOPIC_PREFIX "iot/"
|
#define TOPIC_PREFIX "iot/"
|
||||||
|
|
||||||
|
#define OTA_URL "http://" MQTT_BROKER "/"
|
||||||
|
|
||||||
#define BTN_PIN 0
|
#define BTN_PIN 0
|
||||||
#define LED_PIN 2
|
#define LED_PIN 2
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,10 @@ mosquitto:
|
||||||
image: toke/mosquitto
|
image: toke/mosquitto
|
||||||
ports:
|
ports:
|
||||||
- "1883:1883"
|
- "1883:1883"
|
||||||
|
|
||||||
|
nginx:
|
||||||
|
image: nginx
|
||||||
|
volumes:
|
||||||
|
- ota:/usr/share/nginx/html
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
import time
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# The callback for when the client receives a CONNACK response from the server.
|
||||||
|
def on_connect(client, userdata, rc):
|
||||||
|
print("Connected with result code "+str(rc))
|
||||||
|
# Subscribing in on_connect() means that if we lose the connection and
|
||||||
|
# reconnect then subscriptions will be renewed.
|
||||||
|
client.subscribe("light/status")
|
||||||
|
client.subscribe("#")
|
||||||
|
client.publish("iot/" + sys.argv[1] + "/" + sys.argv[2], sys.argv[3])
|
||||||
|
|
||||||
|
# The callback for when a PUBLISH message is received from the server.
|
||||||
|
def on_message(client, userdata, msg):
|
||||||
|
print(str(time.time())+" "+msg.topic+" "+str(msg.payload))
|
||||||
|
exit()
|
||||||
|
|
||||||
|
client = mqtt.Client("test-client-%d" % random.randint(100, 999))
|
||||||
|
client.on_connect = on_connect
|
||||||
|
client.on_message = on_message
|
||||||
|
|
||||||
|
client.connect("localhost", 1883, 60)
|
||||||
|
|
||||||
|
# Blocking call that processes network traffic, dispatches callbacks and
|
||||||
|
# handles reconnecting.
|
||||||
|
# Other loop*() functions are available that give a threaded interface and a
|
||||||
|
# manual interface.
|
||||||
|
client.loop_forever()
|
|
@ -3,10 +3,16 @@
|
||||||
void SpejsNode::init() {
|
void SpejsNode::init() {
|
||||||
deviceID = WifiStation.getMAC().substring(6, 12);
|
deviceID = WifiStation.getMAC().substring(6, 12);
|
||||||
|
|
||||||
|
currentSlot = 0;
|
||||||
|
if(!rboot_get_last_boot_rom(¤tSlot)) {
|
||||||
|
currentSlot = rboot_get_current_rom();
|
||||||
|
}
|
||||||
|
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.systemDebugOutput(false); // Debug output to serial
|
Serial.systemDebugOutput(false); // Debug output to serial
|
||||||
Serial.print("*** SpejsNode init, running on: ");
|
Serial.print("*** SpejsNode init, running on:");
|
||||||
Serial.println(deviceID);
|
Serial.print(deviceID);
|
||||||
|
Serial.printf(", current rom: %d\r\n", currentSlot);
|
||||||
|
|
||||||
WifiStation.config(WIFI_SSID, WIFI_PWD);
|
WifiStation.config(WIFI_SSID, WIFI_PWD);
|
||||||
WifiStation.enable(true);
|
WifiStation.enable(true);
|
||||||
|
@ -18,12 +24,26 @@ void SpejsNode::init() {
|
||||||
20, *[] {
|
20, *[] {
|
||||||
Serial.println("Connection failed");
|
Serial.println("Connection failed");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
inputs["control"] = MqttStringSubscriptionCallback(&SpejsNode::controlHandler, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpejsNode::keepAliveHandler() {
|
void SpejsNode::keepAliveHandler() {
|
||||||
if(mqtt.getConnectionState() != eTCS_Connected) {
|
if(mqtt.getConnectionState() != eTCS_Connected) {
|
||||||
Serial.println("Reconnecting");
|
Serial.println("Reconnecting");
|
||||||
onConnected();
|
onConnected();
|
||||||
|
} else {
|
||||||
|
uint8_t mode;
|
||||||
|
if(rboot_get_last_boot_mode(&mode)) {
|
||||||
|
if(mode == MODE_TEMP_ROM) {
|
||||||
|
rboot_set_current_rom(currentSlot);
|
||||||
|
Serial.println("Successfuly connected, accepting temp rom");
|
||||||
|
} else {
|
||||||
|
Serial.printf("Not a TEMP ROM boot: %d\r\n", mode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.println("No boot mode info");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,26 +74,104 @@ bool SpejsNode::notify(String key, String value) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpejsNode::registerInput(String key, InputCallback callback) {
|
void SpejsNode::registerInput(String key, MqttStringSubscriptionCallback callback) {
|
||||||
inputs[key] = callback;
|
inputs[key] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpejsNode::mqttCallback(String topic, String value) {
|
void SpejsNode::mqttCallback(String origtopic, String value) {
|
||||||
String devicePrefix = TOPIC_PREFIX + deviceID;
|
String devicePrefix = TOPIC_PREFIX + deviceID;
|
||||||
if(!topic.startsWith(devicePrefix)) {
|
if(!origtopic.startsWith(devicePrefix)) {
|
||||||
Serial.println("ignoring");
|
Serial.println("ignoring");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
topic = topic.substring(devicePrefix.length() + 1);
|
String topic = origtopic.substring(devicePrefix.length() + 1);
|
||||||
|
|
||||||
Serial.println(topic);
|
Serial.println(topic);
|
||||||
Serial.println(value);
|
Serial.println(value);
|
||||||
|
|
||||||
if(inputs.contains(topic)) {
|
if(inputs.contains(topic)) {
|
||||||
Serial.println("dupa");
|
Serial.println("dupa");
|
||||||
inputs[topic](value);
|
inputs[topic](origtopic, value);
|
||||||
} else {
|
} else {
|
||||||
Serial.println("default");
|
Serial.println("unknown topic?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpejsNode::controlHandler(String key, String value) {
|
||||||
|
Serial.println("Control command: " + value);
|
||||||
|
if(value == "ota") {
|
||||||
|
startOTA();
|
||||||
|
} else if(value == "restart") {
|
||||||
|
//System.restart();
|
||||||
|
keepaliveTimer.initializeMs(500, *[] {
|
||||||
|
System.restart();
|
||||||
|
}).start();
|
||||||
|
} else {
|
||||||
|
Serial.println("Invalid command");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpejsNode::startOTA() {
|
||||||
|
uint8_t slot;
|
||||||
|
rboot_config bootconf;
|
||||||
|
String romURL = OTA_URL + deviceID + "/rom0.bin";
|
||||||
|
String spiffsURL = OTA_URL + deviceID + "/spiff_rom.bin";
|
||||||
|
|
||||||
|
Serial.println("Updating...");
|
||||||
|
|
||||||
|
// need a clean object, otherwise if run before and failed will not run again
|
||||||
|
if (otaUpdater) delete otaUpdater;
|
||||||
|
otaUpdater = new rBootHttpUpdate();
|
||||||
|
|
||||||
|
bootconf = rboot_get_config();
|
||||||
|
|
||||||
|
if (currentSlot == 0)
|
||||||
|
slot = 1;
|
||||||
|
else
|
||||||
|
slot = 0;
|
||||||
|
|
||||||
|
Serial.printf("Updating to rom %d.\r\n", slot);
|
||||||
|
|
||||||
|
// flash rom to position indicated in the rBoot config rom table
|
||||||
|
otaUpdater->addItem(bootconf.roms[slot], romURL);
|
||||||
|
|
||||||
|
#ifndef DISABLE_SPIFFS
|
||||||
|
// use user supplied values (defaults for 4mb flash in makefile)
|
||||||
|
if (slot == 0) {
|
||||||
|
otaUpdater->addItem(RBOOT_SPIFFS_0, spiffsURL);
|
||||||
|
} else {
|
||||||
|
otaUpdater->addItem(RBOOT_SPIFFS_1, spiffsURL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
otaUpdater->setCallback(otaUpdateDelegate(&SpejsNode::otaUpdateCallback, this));
|
||||||
|
otaUpdater->start();
|
||||||
|
notify("ota", "started");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpejsNode::otaUpdateCallback(bool result) {
|
||||||
|
Serial.println("In callback...");
|
||||||
|
if(result == true) {
|
||||||
|
// success
|
||||||
|
notify("ota", "finished");
|
||||||
|
|
||||||
|
uint8 slot;
|
||||||
|
|
||||||
|
if (currentSlot == 0)
|
||||||
|
slot = 1;
|
||||||
|
else
|
||||||
|
slot = 0;
|
||||||
|
|
||||||
|
// set to boot new rom and then reboot
|
||||||
|
Serial.printf("Firmware updated, rebooting to rom %d...\r\n", slot);
|
||||||
|
|
||||||
|
rboot_set_temp_rom(slot);
|
||||||
|
|
||||||
|
keepaliveTimer.initializeMs(500, *[] {
|
||||||
|
System.restart();
|
||||||
|
}).start();
|
||||||
|
} else {
|
||||||
|
notify("ota", "failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,96 +2,35 @@
|
||||||
#include <common_config.h>
|
#include <common_config.h>
|
||||||
#include <SmingCore/SmingCore.h>
|
#include <SmingCore/SmingCore.h>
|
||||||
|
|
||||||
typedef void (*InputCallback)(String);
|
|
||||||
|
|
||||||
class SpejsNode {
|
class SpejsNode {
|
||||||
protected:
|
protected:
|
||||||
String deviceID;
|
String deviceID;
|
||||||
String deviceType;
|
String deviceType;
|
||||||
MqttClient mqtt; // (MQTT_BROKER, MQTT_PORT);
|
|
||||||
|
MqttClient mqtt;
|
||||||
|
|
||||||
Timer keepaliveTimer;
|
Timer keepaliveTimer;
|
||||||
|
|
||||||
HashMap<String, InputCallback> inputs;
|
rBootHttpUpdate* otaUpdater = 0;
|
||||||
|
|
||||||
|
HashMap<String, MqttStringSubscriptionCallback> inputs;
|
||||||
|
|
||||||
void onConnected();
|
void onConnected();
|
||||||
void startOTA();
|
void startOTA();
|
||||||
void keepAliveHandler();
|
void keepAliveHandler();
|
||||||
|
|
||||||
|
uint8_t currentSlot;
|
||||||
public:
|
public:
|
||||||
SpejsNode(String _deviceType) :
|
SpejsNode(String _deviceType) :
|
||||||
mqtt(MQTT_BROKER, MQTT_PORT, MqttStringSubscriptionCallback(&SpejsNode::mqttCallback, this)),
|
mqtt(MQTT_BROKER, MQTT_PORT, MqttStringSubscriptionCallback(&SpejsNode::mqttCallback, this)),
|
||||||
//*[](String topic, String message) {
|
|
||||||
// Serial.printf("*** message received @ %s:\n\t%s\n***\n", topic.c_str(), message.c_str());
|
|
||||||
//}),
|
|
||||||
deviceType(_deviceType)
|
deviceType(_deviceType)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
//void registerInput(uint32_t gpio);
|
|
||||||
//void registerOutput(uint32_t gpio);
|
|
||||||
|
|
||||||
bool notify(String key, String value);
|
bool notify(String key, String value);
|
||||||
void registerInput(String key, InputCallback cb);
|
void registerInput(String key, MqttStringSubscriptionCallback cb);
|
||||||
void mqttCallback(String, String);
|
void mqttCallback(String, String);
|
||||||
|
void controlHandler(String, String);
|
||||||
|
void otaUpdateCallback(bool result);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
MqttClient mqtt(MQTT_BROKER, MQTT_PORT, *[](String topic, String message) {
|
|
||||||
Serial.printf("*** message received @ %s:\n\t%s\n***\n", topic.c_str(), message.c_str());
|
|
||||||
});
|
|
||||||
|
|
||||||
Timer keepaliveTimer;
|
|
||||||
String deviceName;
|
|
||||||
|
|
||||||
void startMqttClient()
|
|
||||||
{
|
|
||||||
Serial.println("*** Connecting to MQTT as " + deviceName);
|
|
||||||
|
|
||||||
mqtt.setWill("main/status/" + deviceName, "offline", 1, true);
|
|
||||||
mqtt.connect(deviceName);
|
|
||||||
mqtt.publish("main/status/" + deviceName, "online");
|
|
||||||
|
|
||||||
keepaliveTimer.initializeMs(5000, *[] {
|
|
||||||
mqtt.publish("main/status/" + deviceName, "alive " + String(millis()));
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void init()
|
|
||||||
{
|
|
||||||
deviceName = "switch-" + WifiStation.getMAC().substring(6, 12);
|
|
||||||
|
|
||||||
Serial.begin(SERIAL_BAUD_RATE); // 115200 by default
|
|
||||||
Serial.systemDebugOutput(false); // Debug output to serial
|
|
||||||
|
|
||||||
Serial.println("*** Starting " + deviceName + " ...");
|
|
||||||
|
|
||||||
WifiStation.config(WIFI_SSID, WIFI_PWD);
|
|
||||||
WifiStation.setIP(IPAddress(10, 5, 0, 39), IPAddress(255, 255, 255, 0), IPAddress(10, 5, 0, 1));
|
|
||||||
WifiStation.enable(true);
|
|
||||||
|
|
||||||
WifiAccessPoint.enable(false);
|
|
||||||
|
|
||||||
|
|
||||||
WifiStation.waitConnection(*[] {
|
|
||||||
Serial.println("*** Connection succeeded");
|
|
||||||
startMqttClient();
|
|
||||||
}, 20, *[] {
|
|
||||||
Serial.println("*** Connection failed");
|
|
||||||
});
|
|
||||||
|
|
||||||
attachInterrupt(BTN_PIN, *[] {
|
|
||||||
static int lastSwitch = 0;
|
|
||||||
|
|
||||||
// Debouncing
|
|
||||||
if(lastSwitch + 150 > millis()) {
|
|
||||||
Serial.println("--- debouncing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lastSwitch = millis();
|
|
||||||
|
|
||||||
Serial.println("*** Button pressed");
|
|
||||||
mqtt.publish("light/status", "toggle");
|
|
||||||
}, FALLING);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -22,3 +22,8 @@ include $(SMING_HOME)/Makefile-rboot.mk
|
||||||
else
|
else
|
||||||
include $(SMING_HOME)/Makefile-project.mk
|
include $(SMING_HOME)/Makefile-project.mk
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ota: all
|
||||||
|
-mkdir ../master/ota/$(DEVICE) >/dev/null
|
||||||
|
cp -r out/firmware/* ../master/ota/$(DEVICE)
|
||||||
|
python ../master/ota.py $(DEVICE) control ota
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
MODULES = app ../spejsiot
|
MODULES = app ../spejsiot
|
||||||
DISABLE_SPIFFS = 1
|
DISABLE_SPIFFS = 1
|
||||||
USER_CFLAGS = -I../common
|
USER_CFLAGS = -I../common
|
||||||
|
|
||||||
|
RBOOT_ENABLED ?= 1
|
||||||
|
RBOOT_BIG_FLASH ?= 1
|
||||||
|
SPI_SIZE ?= 4M
|
||||||
|
|
|
@ -0,0 +1,219 @@
|
||||||
|
/* This linker script generated from xt-genldscripts.tpp for LSP . */
|
||||||
|
/* Linker Script for ld -N */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||||
|
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
|
||||||
|
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||||
|
irom0_0_seg : org = 0x40202010, len = 0x42000
|
||||||
|
}
|
||||||
|
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
dport0_0_phdr PT_LOAD;
|
||||||
|
dram0_0_phdr PT_LOAD;
|
||||||
|
dram0_0_bss_phdr PT_LOAD;
|
||||||
|
iram1_0_phdr PT_LOAD;
|
||||||
|
irom0_0_phdr PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Default entry point: */
|
||||||
|
ENTRY(call_user_start)
|
||||||
|
EXTERN(_DebugExceptionVector)
|
||||||
|
EXTERN(_DoubleExceptionVector)
|
||||||
|
EXTERN(_KernelExceptionVector)
|
||||||
|
EXTERN(_NMIExceptionVector)
|
||||||
|
EXTERN(_UserExceptionVector)
|
||||||
|
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||||
|
/* Various memory-map dependent cache attribute settings: */
|
||||||
|
_memmap_cacheattr_wb_base = 0x00000110;
|
||||||
|
_memmap_cacheattr_wt_base = 0x00000110;
|
||||||
|
_memmap_cacheattr_bp_base = 0x00000220;
|
||||||
|
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||||
|
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||||
|
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||||
|
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||||
|
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||||
|
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||||
|
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||||
|
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||||
|
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
.dport0.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_rodata_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.rodata)
|
||||||
|
*(.dport.rodata)
|
||||||
|
_dport0_rodata_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.dport0.literal : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_literal_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.literal)
|
||||||
|
*(.dport.literal)
|
||||||
|
_dport0_literal_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.dport0.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_data_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.data)
|
||||||
|
*(.dport.data)
|
||||||
|
_dport0_data_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
*(.data1)
|
||||||
|
*(.sdata)
|
||||||
|
*(.sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
*(.sdata2)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s2.*)
|
||||||
|
*(.jcr)
|
||||||
|
_data_end = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_phdr
|
||||||
|
|
||||||
|
.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
*(.sdk.version)
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.rodata1)
|
||||||
|
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_table)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.gnu.linkonce.e.*)
|
||||||
|
*(.gnu.version_r)
|
||||||
|
*(.eh_frame)
|
||||||
|
. = (. + 3) & ~ 3;
|
||||||
|
/* C++ constructor and destructor tables, properly ordered: */
|
||||||
|
__dso_handle = ABSOLUTE(.);
|
||||||
|
__init_array_start = ABSOLUTE(.);
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
__init_array_end = ABSOLUTE(.);
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
/* C++ exception handlers table: */
|
||||||
|
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc)
|
||||||
|
*(.gnu.linkonce.h.*)
|
||||||
|
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc_end)
|
||||||
|
*(.dynamic)
|
||||||
|
*(.gnu.version_d)
|
||||||
|
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||||
|
_bss_table_start = ABSOLUTE(.);
|
||||||
|
LONG(_bss_start)
|
||||||
|
LONG(_bss_end)
|
||||||
|
_bss_table_end = ABSOLUTE(.);
|
||||||
|
_rodata_end = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_phdr
|
||||||
|
|
||||||
|
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_start = ABSOLUTE(.);
|
||||||
|
*(.dynsbss)
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.scommon)
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_end = ABSOLUTE(.);
|
||||||
|
_heap_start = ABSOLUTE(.);
|
||||||
|
/* _stack_sentry = ALIGN(0x8); */
|
||||||
|
} >dram0_0_seg :dram0_0_bss_phdr
|
||||||
|
/* __stack = 0x3ffc8000; */
|
||||||
|
|
||||||
|
.irom0.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
_irom0_text_start = ABSOLUTE(.);
|
||||||
|
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||||
|
out/build/app_app.a:*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
*libsming.a:*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
_irom0_text_end = ABSOLUTE(.);
|
||||||
|
_flash_code_end = ABSOLUTE(.);
|
||||||
|
} >irom0_0_seg :irom0_0_phdr
|
||||||
|
|
||||||
|
.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
_stext = .;
|
||||||
|
_text_start = ABSOLUTE(.);
|
||||||
|
*(.UserEnter.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.DebugExceptionVector.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.NMIExceptionVector.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.KernelExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.UserExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.DoubleExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN (16);
|
||||||
|
*(.entry.text)
|
||||||
|
*(.init.literal)
|
||||||
|
*(.init)
|
||||||
|
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
*(.iram.literal .iram.text.literal .iram.text)
|
||||||
|
*(.fini.literal)
|
||||||
|
*(.fini)
|
||||||
|
*(.gnu.version)
|
||||||
|
_text_end = ABSOLUTE(.);
|
||||||
|
_etext = .;
|
||||||
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
|
||||||
|
.lit4 : ALIGN(4)
|
||||||
|
{
|
||||||
|
_lit4_start = ABSOLUTE(.);
|
||||||
|
*(*.lit4)
|
||||||
|
*(.lit4.*)
|
||||||
|
*(.gnu.linkonce.lit4.*)
|
||||||
|
_lit4_end = ABSOLUTE(.);
|
||||||
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get ROM code address */
|
||||||
|
INCLUDE "../ld/eagle.rom.addr.v6.ld"
|
Loading…
Reference in New Issue