Neue Firmware für HM_LC_Sw1PBU_FM mit getrenntem Aktor, Taster + Wechselschalter

Begonnen von jab, 29 Dezember 2013, 22:04:10

Vorheriges Thema - Nächstes Thema

mmattern

Zitat von: unimatrix am 12 Juli 2014, 20:32:15
gibt es neue Erkenntnisse zum Bauen des Bootloaders?

Ich möchte gerne am Anfang des Bootloaders den Watchdog ausschalten. Damit ich in die Applikation eine Reset-Funktion einbauen kann mit Hilfe des Watchdogs. Ziel wäre es, den Bootloader per FHEM Befehl anzuspringen so dass der Schalter nicht stromlos gemacht werden muss.

Ohne das Ausschalten im Bootloader käme es wohl zu einer Reset-Loop.

Alternativ könnte man ggf. den Bootloader einfach anspringen. Aber an welcher Adresse startet der? bei 0x0000... liegt ja die Hauptanwendung.

Hallo Cyberman,

ein paar Erkenntnisse schon (vgl. Issue in Github, https://github.com/jabdoa2/Asksin_OTA_Bootloader/issues/1), nur noch keine Lösung.
Ich gehe davon aus, dass man mal ein Disassembly-Output von Jan neben einen von uns legen muss um zu sehen, wo der Compiler "Unsinn" macht... Es ist auch schon genau die Stelle identifiziert, bei der zumindest der von mir gebaute aussteigt...

Bootloader startet - sofern du die Fuses so gesetzt hast wie in der Anleitung, bei 0xE000 (in Bytes, bzw. 0x7000 in Words).

Du solltest also so in den Bootloader springen können:

typedef void (*BootloaderPtr_t)(void) __attribute__ ((noreturn));

BootloaderPtr_t BootloaderStartPtr = (BootloaderPtr_t)0xE000;
BootloaderStartPtr();


Bin mir nicht absolut sicher, ob man hier die Byte-Adresse oder die in Words (also 0x7000) angeben muss... aber das lässt sich ja leicht testen...

Die Interrupts muss man wahrscheinlich auch noch für den Bootloader-Modus umbiegen, so wird das im Bootloader gemacht:

unsigned char temp;              /* Variable */
/* Interrupt Vektoren verbiegen */
char sregtemp = SREG;
cli();
temp = MCUCR;
MCUCR = temp | (1<<IVCE);
MCUCR = temp | (1<<IVSEL);
SREG = sregtemp;


Ich sehe allerdings jetzt gerade nicht, wie das zu einer Reset-Loop führen sollte... der Bootloader springt nach Timeout in die Applikation, und das Springen in den Bootloader könntest du ja z.B. auf "Config-Button lange drücken" setzen, oder?
Oder man setzt gleich einen BidCos-Code auf, um das dann per FHEM auslösen zu können... klingt spannend!

Viele Grüße
Michael
2x Raspberry Pi, 2x HM-CFG-LAN, 2x HM-CFG-USB, 2x HM-ES-PMSw1-Pl, 3x HM-LC-BL1-FM, 10x HM-LC-Bl1PBU-FM, 6x HM-LC-Sw1PBU-FM-CustomFW, 2x HM-PB-2-WM55-2, 4x HM-PB-6-WM55, 2x HM-SEC-MDIR-2, 6x HM-SEC-RHS, 2x HM-SEC-WIN, 2x HM-Sys-sRP-Pl

unimatrix

Hi Michael,

habs getestet und es funktioniert. Man erkennt an der LED dass er in den BL springt und auch die FW lässt sich dann hochladen.

Mit den Registern muss wohl noch mehr nicht stimmen, habe ich nur gerade nicht im Überblick. Die UART Ausgabe ist danach verbogen. Aber es ist wohl egal, da der FW Upload ja klappt.

Ich meinte damit eine andere Methode, nämlich den Watchdog zu aktivieren und in den Timeout laufen zu lassen (dieser ist aber auf maximal 8 sekunden begrenzt). Das Problem ist, dass der Watchdog dann auch nach dem Reset aktiv bleibt. Einer der ersten Aktionen in einem dazu passenden Bootloader müsste sein, den Watchdog zu deaktivieren. Ansonsten würde der AVR alle maximal 8 Sekunden wieder resetten und man bekäme dieses Problem dann OTA nicht mehr raus sondern nur durch neu Flashen per ISP. Vorteil dieser Methode ist, dass ein echter Reset generiert wird, der keinen Unterschied zu einem Power-Cycle machen dürfte. Somit sind danach auch alle Register usw. sauber.

das ganze über fhem anzutriggern muss somit auch gehen, aber muss eben eingebaut werden. Bin mir im Moment nicht sicher, was dazu der protokollkonforme weg wäre, z.B. ob es dazu einen eigenen Reset-Channel benötigen würde oder ob man das Verhalten durch ein eigenes Register in List0 herbeirufen sollte.

frank

ZitatIch meinte damit eine andere Methode, nämlich den Watchdog zu aktivieren und in den Timeout laufen zu lassen (dieser ist aber auf maximal 8 sekunden begrenzt). Das Problem ist, dass der Watchdog dann auch nach dem Reset aktiv bleibt. Einer der ersten Aktionen in einem dazu passenden Bootloader müsste sein, den Watchdog zu deaktivieren. Ansonsten würde der AVR alle maximal 8 Sekunden wieder resetten und man bekäme dieses Problem dann OTA nicht mehr raus sondern nur durch neu Flashen per ISP. Vorteil dieser Methode ist, dass ein echter Reset generiert wird, der keinen Unterschied zu einem Power-Cycle machen dürfte. Somit sind danach auch alle Register usw. sauber.

das ganze über fhem anzutriggern muss somit auch gehen, aber muss eben eingebaut werden. Bin mir im Moment nicht sicher, was dazu der protokollkonforme weg wäre, z.B. ob es dazu einen eigenen Reset-Channel benötigen würde oder ob man das Verhalten durch ein eigenes Register in List0 herbeirufen sollte.
das war eigentlich der plan von jab, dachte ich. siehe auch hier. http://forum.fhem.de/index.php/topic,18071.msg168345.html#msg168345 und diesen thread http://forum.fhem.de/index.php/topic,23329.msg166287.html#msg166287.

gruss frank
FHEM: 6.0(SVN) => Pi3(buster)
IO: CUL433|CUL868|HMLAN|HMUSB2|HMUART
CUL_HM: CC-TC|CC-VD|SEC-SD|SEC-SC|SEC-RHS|Sw1PBU-FM|Sw1-FM|Dim1TPBU-FM|Dim1T-FM|ES-PMSw1-Pl
IT: ITZ500|ITT1500|ITR1500|GRR3500
WebUI [HMdeviceTools.js (hm.js)]: https://forum.fhem.de/index.php/topic,106959.0.html

mmattern

Zitat von: frank am 14 Juli 2014, 10:24:40
das war eigentlich der plan von jab, dachte ich. siehe auch hier. http://forum.fhem.de/index.php/topic,18071.msg168345.html#msg168345 und diesen thread http://forum.fhem.de/index.php/topic,23329.msg166287.html#msg166287.

gruss frank

Hallo unimatrix,

ok, Frank hatte den relevanten Code zum Abschalten des Watchdogs ja schon herausgesucht:

#include <stdint.h>
    #include <avr/wdt.h>

    uint8_t mcusr_mirror __attribute__ ((section (".noinit")));

    void get_mcusr(void) \
      __attribute__((naked)) \
      __attribute__((section(".init3")));
    void get_mcusr(void)
    {
      mcusr_mirror = MCUSR;
      MCUSR = 0;
      wdt_disable();
    }


Zum reinen Abschalten des Watchdogs sollten nur die Zeilen

      #include <avr/wdt.h>

      ...

      MCUSR = 0;
      wdt_disable();
relevant sein... der Rest dient dazu, MCUSR zu sichern, damit man den Auslöser des Reset auswerten kann.


@unimatrix - also bräuchten wir einen Bootloader, der ganz zu Beginn den Watchdog abschaltet, was bedeutet, dass wir in der Lage sein müssen, einen funktionierenden Bootloader zu bauen... jab - Hilfe!!!

:o
2x Raspberry Pi, 2x HM-CFG-LAN, 2x HM-CFG-USB, 2x HM-ES-PMSw1-Pl, 3x HM-LC-BL1-FM, 10x HM-LC-Bl1PBU-FM, 6x HM-LC-Sw1PBU-FM-CustomFW, 2x HM-PB-2-WM55-2, 4x HM-PB-6-WM55, 2x HM-SEC-MDIR-2, 6x HM-SEC-RHS, 2x HM-SEC-WIN, 2x HM-Sys-sRP-Pl

wires.io

Liebe FHEM-Forumsnutzer,

bin über Umwege auf diesen Thread gekommen und habe die alternative Firmware auch in einem Homematic Forum bekannt gegeben, da möglicherweise auch dort Interesse besteht.

Habe keine FHEM Installation, sondern benutze Homematic klassisch mit der CCU2. Habe bereits zwei solcher Unterputzverschalter - sehr umständlich - über ein Programm, das auf der CCU2 läuft, verknüpft.

Möchte nun eine Direktverknüpfung erzeugen und konnte bereits eine .hex Datei mit der Arduino IDE erzeugen. Dazu zwei Fragen:
- Ergibt sich die HMID, die ich in Register.h setzen muss aus der Geräte-ID KEQ0abcdef als 0xab 0xcd 0xef?
- Habe als Board "Jabduino ATmega644" und nicht "Jabduino ATmega644A" eingetragen, da bei Letzterem das Compilieren mit "nur für Assembler" aussteigt. Ist das so richtig?

Wie muss ich weiter vorgehen?
- .hex mit avrdude auf den OTA_bootloader "flashen"? Geht das auch unter Linux oder Windows (habe keinen Raspberry PI o.ä.)?
- Das Resultat in ein .tar.gz packen / konvertieren? Wie gehe ich da vor?
- Mit der CCU2 ein Over-the-air Update durchführen?

Danke (und Entschuldigung für die Anfängerfragen),

Christian.

unimatrix

Zitat von: mmattern am 14 Juli 2014, 10:44:35
@unimatrix - also bräuchten wir einen Bootloader, der ganz zu Beginn den Watchdog abschaltet, was bedeutet, dass wir in der Lage sein müssen, einen funktionierenden Bootloader zu bauen... jab - Hilfe!!!

genau - das meinte ich. Den dann einbauen ist ja simpel.

In der Zwischenzeit beschäftige ich mich damit, den Code auf die neueste Library-Version zu portieren. Somit kann ich mich gleich weiter mit der Lib vertraut machen. Habe schon eine Version soweit, aber nun fehlt mir praktisch der Schaltplan von dem Schalter, da ja die Pinbelegung nicht der Standardbelegung der Lib entspricht. In der jetzigen Version des SChalters werde ich aus den Defines nicht ganz schlau.

Ich finde dort


#define PORT_SPI_MISO            PINB
#define BIT_SPI_MISO             6
#define PORT_SPI_SS              PORTB
#define BIT_SPI_SS               4
// #define GDO0                     2


..was ja schön ist, und mir sagt (mithilfe des Jabduino 644a mappings) dass MISO an Pin PB6 = Digital Pin 6 angeschlossen ist. Aber was ist mit den anderen Pins (MOSI, CS, etc.)


mmattern

Zitat von: unimatrix am 14 Juli 2014, 14:12:29
..was ja schön ist, und mir sagt (mithilfe des Jabduino 644a mappings) dass MISO an Pin PB6 = Digital Pin 6 angeschlossen ist. Aber was ist mit den anderen Pins (MOSI, CS, etc.)

Hallo unimatrix,

laut http://matthiasm.com/homematic_small_steps.html:

ZitatPins und Ports

Fix in den Schaltplan geschaut:

PA0 (ADC) hängt am Stromsensor
PB0 steuert die LED
PB4 ist /CS für den Trasceiver
PB5 ist MOSI
PB6 ist MISO
PB7 ist SCK, also der Takt für die SPI Schnittstelle
PC0 ist SCL und spricht mit dem Flash RAM
PC1 ist SDA, also der zweite Teil des i2c Bus
PD0 geht über die Wippe an Masse - schade, dies wäre auch RxD
PD2 ist GDO0 and Transceiver und kann Interrupts auslösen - gut!
PD3 geht an GDO2 und kann das ebenfalls - sehr gut!
PD4 schaltet das Relais
PD6 geht ebenfalls an die Wippe
PD7 geht über den Config Taster an Masse
PD1 ist TxD

Ich schaue auch mal, ob ich noch einen Schaltplan habe - ist bei den Komplettbausätzen ja immer dabei...
2x Raspberry Pi, 2x HM-CFG-LAN, 2x HM-CFG-USB, 2x HM-ES-PMSw1-Pl, 3x HM-LC-BL1-FM, 10x HM-LC-Bl1PBU-FM, 6x HM-LC-Sw1PBU-FM-CustomFW, 2x HM-PB-2-WM55-2, 4x HM-PB-6-WM55, 2x HM-SEC-MDIR-2, 6x HM-SEC-RHS, 2x HM-SEC-WIN, 2x HM-Sys-sRP-Pl

mmattern

Zitat von: wires.io am 14 Juli 2014, 12:21:05
- Ergibt sich die HMID, die ich in Register.h setzen muss aus der Geräte-ID KEQ0abcdef als 0xab 0xcd 0xef?

Manche behaupten, die HMID ließe sich aus der Seriennummer errechnen - ich weiß nicht, ob das stimmt bzw. wie das geht.
Ist aber auch eigentlich egal, du kannst es in der Register.h so setzen, wie du es brauchst. Auf jeden Fall muss die HMID eindeutig sein.
z.B. könntest du erstmal den Schalter mit der originalen Firmware in FHEM anlegen lassen durch Pairing mit der Zentrale und dann die HMID auslesen.
Und dann ab nach Register.h damit.
Wenn du nur einen Schalter hast, kannst du eigentlich auch die fertige Firmware von hier nehmen:
https://owncloud.isengard.at/public.php?service=files&t=0df535e31ad6999664f0e84c95bd2ea5

Ist dann KEQ0123456, HMID ABCDEF

Zitat von: wires.io am 14 Juli 2014, 12:21:05
- Habe als Board "Jabduino ATmega644" und nicht "Jabduino ATmega644A" eingetragen, da bei Letzterem das Compilieren mit "nur für Assembler" aussteigt. Ist das so richtig?
ATmega644 sollte so funktionieren.

Zitat von: wires.io am 14 Juli 2014, 12:21:05
Wie muss ich weiter vorgehen?
- .hex mit avrdude auf den OTA_bootloader "flashen"? Geht das auch unter Linux oder Windows (habe keinen Raspberry PI o.ä.)?
- Das Resultat in ein .tar.gz packen / konvertieren? Wie gehe ich da vor?
- Mit der CCU2 ein Over-the-air Update durchführen?

Vorsicht - .hex ist für avrdude und wird per ISP/Kabel geflashed, .eq3 ist für OTA-Flash.
Wie man aus dem .bin (im ELF-Format) ein .eq3 macht, steht hier: https://github.com/jabdoa2/Asksin_OTA_Bootloader:
Zitat
Convert payload and flash:

You need to convert your elf file to binary first (For arduino GUI you can find this in /tmp/buildXXXXX/)
avr-objcopy -j .text -j .data -O binary payload.elf payload.bin
Use the converter (need php-cli):
php convert.php payload.bin payload.eq3 # convert to eq3 hex format
tar -czf payload.tar.gz payload.eq3 # create .tar.gz for homematic windows tool

.tar.gz ist für das Windows-Update-Tool gedacht, .eq3 funktioniert mit ota-flash aus https://git.zerfleddert.de/cgi-bin/gitweb.cgi/hmcfgusb




2x Raspberry Pi, 2x HM-CFG-LAN, 2x HM-CFG-USB, 2x HM-ES-PMSw1-Pl, 3x HM-LC-BL1-FM, 10x HM-LC-Bl1PBU-FM, 6x HM-LC-Sw1PBU-FM-CustomFW, 2x HM-PB-2-WM55-2, 4x HM-PB-6-WM55, 2x HM-SEC-MDIR-2, 6x HM-SEC-RHS, 2x HM-SEC-WIN, 2x HM-Sys-sRP-Pl


unimatrix

Zitat von: mmattern am 14 Juli 2014, 15:24:30
Ich schaue auch mal, ob ich noch einen Schaltplan habe - ist bei den Komplettbausätzen ja immer dabei...

Danke. Ich habe die auch aus Bausätzen gebaut und nicht bedacht, dass die Schaltpläne später als PDF nicht so einfach zu beziehen sind, nun habe ich sie nicht mehr :(

Danke für die Infos - es funktioniert ! Nun habe ich zuerst mal den 6-fach Taster aus Examples so angepasst dass er mit der aktuellen Lib-Struktur funktioniert und nun die Ports auf den 644a geändert und nun habe ich einen HM-UP Aktor der sich als 6-Kanal Taster verhält

Das ist wie Weihnachten!

Mir ist noch was wegen dem Bootloader eingefallen. Wenn man dann den Reboot einbaut, dann hat man ein Problem, wenn das Flash-OTA abbricht z.B. wegen Übertragungsfehlern. Dann wird in eine nicht laufende Applikation gesprungen und dann geht natürlich kein Reboot mehr:

Option 1: Flash-Prozess erweitern damit der Bootloader unvollständige Uploads erkennt. Möglicherweise nicht so einfach
Option 2: Den Watchdog im Bootloader nicht ausschalten, sondern regelmäßig resetten. Den Watchdog dann erst in der Applikation ausschalten. Weiß aber nicht, ob eine unvollständig geflashte Applikation den dann ggf. auch ausschaltet, somit würde es nichts helfen...

trilu

Watchdog ausschalten in der Applikation ist keine gute Idee, ich brauche den Watchdog für das Powermanagement :-)
Umkonfigurieren wäre vermutlich besser dann kann man den Watchdog weiterhin als Timer nutzen...

unimatrix

Ja, war schlecht formuliert. Ich weiß, dass der WD als Timer verwendet wird.

Nun warten wir sowieso auf einen baubaren Bootloader dann wird sich das schnell lösen lassen.

Ich mach erstmal mit meinem Schalter weiter. Die Lib ist inzwischen echt gut geworden und sehr übersichtlich. Ich bin wirklich begeistert. Das ist wie ein Baukasten wo man sich schnell was zusammenschustert...ich genieße gerade den kurzen Glücksmoment wo ich mit einer kleinen wild verdrahteten Platine (HM_LC_Sw1PBU_FM) das Licht im Flur dimmen kann und meine Frau hält mich für total durchgeknallt....

mmattern

Zitat von: unimatrix am 14 Juli 2014, 20:56:37
Danke. Ich habe die auch aus Bausätzen gebaut und nicht bedacht, dass die Schaltpläne später als PDF nicht so einfach zu beziehen sind, nun habe ich sie nicht mehr :(

Here you go...

Scan des Schaltplans für den Schaltaktor und - da im selben Heft - auch für den nahen Verwandten, den Rolladenaktor...
Hat sich an dem eigentlich auch schon mal jemand mit einer Custom Firmware versucht? Die Kontakte zum Programmieren per ISP sind definitiv auch auf der Platine... und auch hier wäre es interessant, das interne Peering zwischen Tastern und Relais auftrennen zu können...

Viele Grüße
Michael
2x Raspberry Pi, 2x HM-CFG-LAN, 2x HM-CFG-USB, 2x HM-ES-PMSw1-Pl, 3x HM-LC-BL1-FM, 10x HM-LC-Bl1PBU-FM, 6x HM-LC-Sw1PBU-FM-CustomFW, 2x HM-PB-2-WM55-2, 4x HM-PB-6-WM55, 2x HM-SEC-MDIR-2, 6x HM-SEC-RHS, 2x HM-SEC-WIN, 2x HM-Sys-sRP-Pl

mmattern

Zitat von: unimatrix am 14 Juli 2014, 21:35:39
Nun warten wir sowieso auf einen baubaren Bootloader dann wird sich das schnell lösen lassen.

Ist jab wirklich der einzige, der einen funktionsfähigen Bootloader bauen kann?
Falls es jemanden gibt: Könntest du bitte mal den Bootloader mit der Option "-g" (baut Debug-Infos in das ELF-File) bauen und dann das Disassembly mittels
avr-objdump -d -M intel -S bootloader.elf > bootloader-dis.txt
erzeugen? Das Ergebnis sowie die exakten Sourcen wären interessant... dann können wir nämlich das funktionierende und nicht funktionierende File mittels Text Compare vergleichen und werden schnell sehen, wo der Compiler unterschiedlichen Code erzeugt...

Der von mir gebaute Bootloader hängt beweisbar genau nach dem Einschalten der Interrupts mittels sei():

// map to correct interrupt table for bootloader
setup_interrupts_for_bootloader();

// setup timer for timeout counter
setup_timer();

// setup interrupts for cc1100
setup_cc1100_interrupts();

// init uart
uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) );

// Activate interrupts
sei();


Zitat von: unimatrix am 14 Juli 2014, 21:35:39
[...] wo ich mit einer kleinen wild verdrahteten Platine (HM_LC_Sw1PBU_FM) das Licht im Flur dimmen kann [...]

Du kannst jetzt echt mit dem Schaltaktor *dimmen*? Kannst du deine Sourcen mal posten oder in Github einstellen?

Cool...  8)
2x Raspberry Pi, 2x HM-CFG-LAN, 2x HM-CFG-USB, 2x HM-ES-PMSw1-Pl, 3x HM-LC-BL1-FM, 10x HM-LC-Bl1PBU-FM, 6x HM-LC-Sw1PBU-FM-CustomFW, 2x HM-PB-2-WM55-2, 4x HM-PB-6-WM55, 2x HM-SEC-MDIR-2, 6x HM-SEC-RHS, 2x HM-SEC-WIN, 2x HM-Sys-sRP-Pl

jab

Moin,

das Problem ist, dass ich mein Bastelnotebook aktuell verliehen habe. Daher habe ich die exakte Buildumgebung nicht. Ich hatte nach dem Update von Ubunutu 12.04 auf 14.04 auch Probleme mit dem bauen. Daher habe ich wie in der Firmware auch das Flashen gefixt (dem Standard entsprechend). Siehe: https://github.com/jabdoa2/Asksin_OTA_Bootloader/commit/ce4a29bf86d136db78d518fe47efa82735654076. Mit GCC 4.6 sollte der Code davor auf jeden Fall und der danach eigentlich auch laufen.

Tut mir Leid dass ich aktuell so wenig Zeit habe. Ich muss mit auf meinem anderen Rechner erstmal wieder eine Umgebung zum Basteln bauen. An mein Notebook komme ich die Tage vermutlich noch mal dran. Dann mache ich den Bootloader Debug Build.

@unimatrix: Ein update auf die aktuelle Firmware will ich auch noch machen für den Aktor. Hast du das fertig? Wenn ja können wir das gerne auch auf github packen (je nach Status erstmal als Branch).

Gruß,
Jan