Als erstes sollte man sich das mal durchlesen:
MDK5 getting started
CMSIS-Driver (Keil)
Tools von ST
- ( Clock-Konfigurations Tool (Excel), … )
Keil - Migrate ARM Compiler 5 to ARM Compiler 6
STVP-STM32 - ST Visual Programmer STM32
Die alte Datei am besten vorher sichern. Da das ganze Handling für die Einstellungen der Farben in der Keil IDE sehr umständlich ist, habe ich obige Vorlage erstellt.
Hinweis: In dieser Datei sind auch meine Templates gespeichert (z.B. für doxygen Blöcke)
Und so sieht es aus
Ansicht global.prop (obiger Link kann direkt gedownloaded werden)
*** error 65: access violation at 0x40021000 : no 'read' permission
Mit foglenden Mapping lässt sich das Problem lösen:
MAP 0x40000000, 0x400FFFFF READ WRITE
Damit man nun nicht immer händisch mit den Bereich im „Memory Map“ im Debugger Menü eintragen muss,
kann man eine „Initializiation File“ anlegen welches den MAP-Befehl enthält.
Hier werden dann die Rechte für den Speicherbereich von 0x40000000 bis 0x400FFFFF auf „Read“ und „Write“ gesetzt.
Falls noch weitere Speicherbereiche benötigt werden, müssen dies hier ebenfalls eingetragen werden.
(simu_stm32f105.ini)
Nun erscheinen für den STM32F103 beim Debuggen unter Peripherals komfortablere Menüeinträge für die Peripeherie.
Wie dies auch für den STM32F105 funktioniert, habe ich noch nicht rausgefunden.
In der DLL konnte ich folgende Parameter (somit werden wohl bloss diese Prozessoren unterstützt) finden:
'STM32F101T6', 'STM32F101RD','STM32F103T6', 'STM32F101ZE' 'STM32F101T8', 'STM32F101RE','STM32F103T8', 'STM32F103RE' 'STM32F101C6', 'STM32F101V8','STM32F103C6', 'STM32F103V8' 'STM32F101C8', 'STM32F101VB','STM32F103C8', 'STM32F103VB' 'STM32F101CB', 'STM32F101VC','STM32F103CB', 'STM32F103VC' 'STM32F101R6', 'STM32F101VD','STM32F103R6', 'STM32F103VD' 'STM32F101R8', 'STM32F101VE','STM32F103R8', 'STM32F103VE' 'STM32F101RB', 'STM32F101ZC','STM32F103RB', 'STM32F103ZC' 'STM32F101RC', 'STM32F101ZD','STM32F103RC', 'STM32F103ZD' 'STM32F101RD', 'STM32F101ZE','STM32F103RD', 'STM32F103ZE' 'ST_bare' 'CortexM3' 'STM32F217IG'
set *0xE0042004 = 0x7E3FFF07
das DBG-Register beim Starten des Debuggers mit den passenden Werte beschreiben.
# Enable Debug connection in low power modes (DBGMCU->CR) set 0xE0042004 = (0xE0042004) | 0x7
als Beispiel für andere Schreibweise
hier werden die unteren 3-Bits gesetzt.
#if !defined HSE_VALUE #ifdef STM32F10X_CL #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #else #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* STM32F10X_CL */ #endif /* HSE_VALUE */Aus diesem Grund sollte das MAKRO HSE_VALUE in den C/C++ Compiler Optionen immer auf den den richtigen Wert gesetzt werden.z.B.
HSE_VALUE=8000000
#ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ printf("\n##########[Error]: Zeile: %d in der Datei: %s\n\n",line,file); { u32 i=0; for (i=0;i<120000;i++) { #ifdef WATCHDOG_AKTIV vResetWdg(); #endif } } while (1) { } } #endifHier wird dann die entsprechende Fehlerzeile über UART ausgegeben, bevor dann in der Endlos-Schleife beim aktivierten Watchdog-Timer ein Reset ausgelöst wird.
int main(void) { RCC_Configuration(); // Zuerst den Clock konfigurieren SystemCoreClockUpdate(); if (SysTick_Config(SystemCoreClock / 1000)) { // dann den Systick auf 1ms setzen // Capture error while (1); } NVIC_Configuration(); ....Und hier noch meine Clock-Konfiguration:
/** * @brief RCC_Configuration - Configures the different system clocks. * * Hier wird nun nachträglich der Takt auf 72MHz ( 32MHz bei L100) gestellt (HSE 8MHz => PLL => 32 MHz) (nur bei L100) * @attention Wenn der Speicher knapp wird dann auf diese Funktion verzichten, und nur die Startup-Konfiguration verwenden (diese steht aber noch auf 24 MHz) * @param None * @retval None */ static void RCC_Configuration(void){ RCC_DeInit(); // RCC system reset(for debug purpose) RCC_HSEConfig(RCC_HSE_ON); // Enable HSE HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready #ifdef PROZESSOR_FAMILY_STM32LXX if(HSEStartUpStatus == SUCCESS){ FLASH_ReadAccess64Cmd(ENABLE); // Enables read access to flash by 64 bits FLASH_PrefetchBufferCmd(ENABLE); // Enable Prefetch Buffer FLASH_SetLatency(FLASH_Latency_1); // ???? RCC->APB1ENR |= RCC_APB1ENR_PWREN; // Power enable PWR->CR = PWR_CR_VOS_0; // Select the Voltage Range 1 (1.8 V) while((PWR->CSR & PWR_CSR_VOSF) != RESET) { // Wait Until the Voltage Regulator is ready }; RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK RCC_PCLK1Config(RCC_HCLK_Div1); // PCLK1 = HCLK RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //by aw als Quelle für den SysClk PLL1 verwenden RCC_PLLConfig(RCC_PLLSource_HSE, RCC_PLLMul_12 , RCC_PLLDiv_3);// nun 32MHz // PLL konfigurieren: HSE * 12 / 3 = 96 Mhz /3 = 32 MHz RCC_PLLCmd(ENABLE); // PLL einschalten while(RCC_GetSYSCLKSource() != 0x0C) // 0x0C: PLL used as system clock { }; RCC_HSICmd(DISABLE); //deAktiviert den internen Highspeed Oszillator. #ifdef PROZESSOR_FAMILY_STM32LXX RCC_MSICmd(DISABLE); #endif } // end HSE Startup Success #else if(HSEStartUpStatus == SUCCESS){ FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Enable Prefetch Buffer RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK // PCLK1 = HCLK RCC_PCLK1Config(RCC_HCLK_Div2); // by AW (72MHz/2 = 36 MHz) wegen Umstelllung auf 72MHz Systemtak // Achtung Timertakt verdoppelt sich dann ??? RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //by aw als Quelle für den SysClk PLL1 verwenden RCC_PLLConfig(RCC_PLLSource_PREDIV1,RCC_PLLMul_9); // PLL konfigurieren: HSE / 1 * 9 = 72MHZ RCC_PLLCmd(ENABLE); // PLL einschalten while(RCC_GetSYSCLKSource() != 0x08) // by aw warten bis PLL als Systemquelle genommen wird { } // test von Aw RCC_HSICmd(DISABLE); //deAktiviert den internen Highspeed Oszillator, Beim Flashspeichern, darf der interne nicht abgschaltet werden } // end success #endif } //end RCC_Configuration
Hinweis das Makro PROZESSOR_FAMILY_STM32LXX wird von mir im Header definiert, wenn ich einen STM32L1xx Type verwende:
//#define PROZESSOR_FAMILY_STM32LXX // Makro zum aktivieren, dass die STM32LXX-Variante // verwendet werden soll
CK_CNT = fCK_PSC / (PSC[15:0] + 1)Daraus folgt dann z.B. für einen Timerclock von 10kHz := 72 Mhz / (prescaler +1)
//! PWM Grundfrequenz für Timer2 (960 Hz) #define TIMER2_PWM_FREQUENZ (960) // Grundfrequenz der PWM //! Timer2 Takt auf 8 MHz #define TIMER2_CLOCK (8000000) // Timer2 Clock wird auf 8 MHz festgelegt ( SYSCLK_FREQ_72MHz) //! Prescaler Wert für den Timer1 #define TIMER2_PRESCACLER ( (vu16) ((SystemCoreClock / TIMER2_CLOCK) - 1)) //! PWM Timer2 Period um auf die 960 Hz zu kommen. #define TIMER2_PWM_PERIOD (0x208D) // (0x109E)
und noch ein Beispiel für die PWM initialisierung von 4 PWM-Kanäle:
header.h: //! PWM Timer2 Period um auf die 960 Hz zu kommen. #define TIMER2_PWM_PERIOD (0x208D) // (0x109E) typedef enum extern_inputs_name_en { EXTERN_MOTOR_1 , EXTERN_MOTOR_2 , EXTERN_MOTOR_3 , EXTERN_MOTOR_4 , EXTERN_COUNTS_MOTOR_INPUTS } extern_inputs_name_t; typedef volatile struct pwmStatus_st { struct pwm_st { u32 dutyCycle; u32 newDutyCycle; // wenn wahr dann neuen Wert setzen } pwm[EXTERN_COUNTS_MOTOR_INPUTS]; struct pwm_timer_st { u16 CCRx_Val ; // Wert für die Peridodendauer vom Timer2 Channel x (1-4) void (*pTimSetCompare)(TIM_TypeDef* TIMx, uint16_t compare); // Zeiger auf die TIM_SetCompare Funktion void (*pTimOcInit)(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct); // Zeiger auf die OCxInit Funktion void (*pTimOcPreload)(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload); } pwm_timer[EXTERN_COUNTS_MOTOR_INPUTS]; } pwmStatus_t; extern pwmStatus_t pwmStatus; extern pwmStatus_t* const pPwmStatus; main.c: //! PWM Statusflags über den PWM-Systemzustand pwmStatus_t pwmStatus = { { { PWM_DEFAULT_DUTY_CYCLE,1 } , { PWM_DEFAULT_DUTY_CYCLE,1 } , { PWM_DEFAULT_DUTY_CYCLE,1 } , { PWM_DEFAULT_DUTY_CYCLE,1 } } , { { 0x00 , TIM_SetCompare1, TIM_OC1Init, TIM_OC1PreloadConfig } //CCR, TimeSetCompare(), TIM_OCxInit(), , { 0x00 , TIM_SetCompare2, TIM_OC2Init, TIM_OC2PreloadConfig } , { 0x00 , TIM_SetCompare3, TIM_OC3Init, TIM_OC3PreloadConfig } , { 0x00 , TIM_SetCompare4, TIM_OC4Init, TIM_OC4PreloadConfig } } }; pwmStatus_t* const pPwmStatus = &pwmStatus; /** * @brief Timer2 Kanäle 1-4 für das PWM Ausgangssignal initialisieren * * PWM-Frequenz 940 Hz für alle Kanäle * PORT A1 (T2.1n) * PORT A2 (T2.2n) * PORT A3 (T2.3n) * PORT A4 (T2.4n) * @param u16 defaultTast * @retval None */ void vInitTimer2PWM(u32 defaultTast) { u32 i; // TIM2 clock enable für das Licht PWM-Signal Test RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // Timer2 Konfiguration PBA2 // Tim2-CLK= auf 4 Mhz festlegen // Time base configuration // PWM Frequenz soll (f= 940 Hz) sein: // allgemein: f=TimerCLK/(ARR+1) ==> ARR=(4 MHz/940Hz)-1 = 4254,32 = 4254 = 109E 0x14F1 // ==> ARR=(8 MHz/940Hz)-1 = 8509,64 = 8510 = 213E PrescalerValue = (vu16) (SystemCoreClock / TIMER2_CLOCK) - 1; // 17 (8 für ( Mhz) TIM_TimeBaseStructure.TIM_Period = TIMER2_PWM_PERIOD ; // 0x109E ==> PWM = 940 Hz TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue; // Timer1 Clk=4 MHz TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // keine weiterer Teiler TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // Vorwärtszähler //TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; // Nur bei Timer1 und Timer8 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // TIM1 Channel3 duty cycle = (TIM1_CCR3/ TIM1_ARR)* 100 = 25% for(i=0; i<EXTERN_COUNTS_MOTOR_INPUTS;i++) { pPwmStatus->pwm_timer[i].CCRx_Val = SetPWM_Tast(defaultTast); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse = pPwmStatus->pwm_timer[i].CCRx_Val; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; pPwmStatus->pwm_timer[i].pTimOcInit(TIM2, &TIM_OCInitStructure); pPwmStatus->pwm_timer[i].pTimOcPreload(TIM2, TIM_OCPreload_Enable); } /* nicht notwendig // Update registers TIM1->EGR |= (1 << TIM_EGR_UG); */ TIM_ARRPreloadConfig(TIM2, ENABLE); /* TIM2 enable counter */ TIM_Cmd(TIM2, ENABLE); // Main Output Enable //nur bei Timer 1, 8 // TIM_CtrlPWMOutputs(TIM2, ENABLE); }
const char string[] __attribute__((at(0x0xxxxxxx)) = "Version 1.xxxxdfdf";
NVIC_SystemReset();
__NVIC_SystemReset();
Wobei mittels Makrodefinition auch der alte Name weiterhin verwendet werden kann.
Und noch ein paar Tipps:
Die ST-LINK/V2-1 auf den NUCLEO und Discovery-Boards können auf ein J-Link OB geflasht werden.
Die Anleitung von Segger ist hier:
ST-LINK zu J-Link von Segger
Diverse andere Projekte verwenden auch den Tiny-USB Stack um für Ihren eigenen Bootloader:
Normalerweise verwende ich mein JTAG Standardkabel (und Belegung) um die ST's zu programmieren.
Da ich immer wieder danach gefragt werde, hier mal die einfachste Variante (SWD Schnittstelle) hier werden nur 4 Verbindungen benötigt. Die Spannungsversorgung des Prozessors mache ich immer mit dem USB Verbindungskabel.
ST-LINK ←→ Interface (meine STM32 Hardware)
1 ---- Vdd -----2 4 ---- GND ---- 4 7 ---- TMS ---- 8 (SWDIO) 9 ---- TCK ---- 7 (SWCLD)
Und hier noch ein Bild: SWD Verbindungen
Dieser USB-Stick Klone hat den Vorteil, dass er auch die Versorgungsspannung liefert. Dafür ist er halt etwas langsamer und unterstützt nur das SWD-Schnittstelle. Dieses Teil hatte ich mir nur für Testzwecke zu gelegt.
ST-Klone ←→ Interface (meine STM32 Hardware)
1 ---- Reset ---- 1 (optional) 2 ---- SWDIO ---- 8 (TMS) 4 ---- GND ---- 4 6 ---- SWCLK ---- 7 (TCK) 7 ---- +3,3V ---- 2 (+3,3V MCU)
Sehr einfaches Eval-Board. Hat im Prinzip nur zwei LEDs und einen Taster als Input. Ist aber für kurze Tests gut geeignet
die beiden anderen LEDS (LD1, LD2) sind fest verdraht und sind für PC-Board Kommunikation (LD1) und Power LED (LD2) vorbehalten.
Hinweis zu STM32CubeIde und Debugging - In den neueren Versionen wird das Debugging dieses Board nicht unterstützt (wegen ST-LINK V1 auf dem Board). Deswegen verwende ich dann den BMP oder einen ST-LINK-V2, d.h.:
verbinden.
Ich habe die „Moving Tux Demo“ mal probeweise auf dem Disco1-Board installiert. Eine kurze Beschreibung von den Abweichungen der Installation und die binär Dateien findet ihr hier:
Da bei der MovinTux Demo auch OpenOCD installiert wird kann man auch den GDB von den ARM-Tools aus dem openOCD Ordner verwenden. Als erstes muss aber der ST-Link GDB-Server mit:
Hier geht's zu meiner Projektseite für STM32F429 USB Bootloader
ST bietet noch folgendes an:
Habe ich mit dem 429 Discoveryboard getestet. Hinweise um den Bildschirm zu um 90° zu drehen:
Hier mein erstes Testprojekt für das Lüftermenü:
Hier geht's zum meinen LVGL-Notizen
export env SWT_GTK3=0
ausführen.
Step-by-Step: STM32 Development Environment with OpenOCD and Visual Studio Code (Linux)
32 Runtime Libs unter Ubuntu 16.04
install all dev and docs
Unter Ubuntu am besten folgende vorgehensweise (auch für 18.04):
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg sudo sh -c 'echo "deb [arch=amd64] https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list' sudo apt update sudo apt install code
Hat den Vorteil das man auch immer die aktuellste Version mittels apt updaten kann. Ab 18.04 ist VS-Code als Package im Software-Center enthalten, aber halt nicht immer ganz aktuell
Hinweis ab der Version V3.0 hat sich die STCAN_MSG Struktur geändert (vereinfacht). Deshalb müssen bestehende Simulationen angepasst werden. Die automatisch Konvertierung beim Importieren einer älteren Version hat bei mir nicht funktioniert. Eventuell lags daran, dass meine Simulationen schon etwas älter sind und im Header die Busmaster Version: BUSMASTER VERSION [1.7.1] angegeben war.
Hier nun die neu Struktur:
class STCAN_MSG { unsigned int id; bool isExtended; bool isRtr; unsigned char dlc; unsigned char cluster; unsigned char data[64]; unsigned long timeStamp; bool isCanfd; // To set data bool byteAt(int index, unsigned char val); bool wordAt(int index, unsigned short val); bool longAt(int index, unsigned long val); // To get data unsigned char byteAt(int index); unsigned short wordAt(int index); unsigned long longAt(int index); };*Cluster ist die CAN-Kanalnummer vom Interface
Da der integrierte Code Editor vom Busmaster grausam ist, habe ich jetzt eine Lösung gefunden um den Visual Studio Code Editor für die Busmaster Knoten Simulation zu verwenden inkl. der IntelliSense Funktionalität und compilieren des Quellcodes direkt aus VS Code herraus.
Hier folgt nun eine kurze Beschreibung wie man den Visual Studio Editor konfigurieren kann damit man für die Busmaster Simulationen die IntelliSense zur Verfügung steht und man auch direkt unter VS Code compilieren kann, d.h. direkt die DLL Datei für den Busmaster erzeugen kann.
Hier für müssen 2 Konfigurations Dateien angelegt werden:
Durch den angepassten „problemMatcher“ werden auch die Fehlermeldungen beim Compilieren in das Problemfenster übernommen, und man kann mit einem Mausklick direkt zur fehlerhaften Zeile springen.
Legendlich der Dateiname ist dann in der alten WIN/MSDOS Schreibweise.
Hier folgt nun eine kurze Beschreibung der wichtigsten Einträge:
{ "name": "Win32", "intelliSenseMode": "clang-x64", "includePath": [ "${workspaceRoot}", "C:/Program Files (x86)/BUSMASTER_v3.2.2/SimulatedSystems/Include", "C:/MinGW/lib/gcc/mingw32/5.1.0/include/c++", "C:/MinGW/lib/gcc/mingw32/5.1.0/include/c++/mingw32", "C:/MinGW/lib/gcc/mingw32/5.1.0/include/c++/backward", "C:/MinGW/lib/gcc/mingw32/5.1.0/include", "C:/MinGW/include", "C:/MinGW/lib/gcc/mingw32/5.1.0/include-fixed" ], "defines": [ "_DEBUG", "UNICODE", "__GNUC__=6", "__cdecl=__attribute__((__cdecl__))" ], "browse": { "path": [ "C:/Program Files (x86)/BUSMASTER_v3.2.2/SimulatedSystems/Include", "C:/MinGW/lib/gcc/mingw32/5.1.0/include", "C:/MinGW/lib/gcc/mingw32/5.1.0/include-fixed", "C:/MinGW/include/*" ], "limitSymbolsToIncludedHeaders": true, "databaseFilename": "" } }
Hinweis: Die Pfade bei den markierten Zeilen müssen eventuell angepasst werden.
{ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "build OBD_Simulator", "type": "shell", "command": "make -f OBD_Simulatormake", "problemMatcher": [ { "owner": "cpp", "fileLocation": "absolute", "pattern": { "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5 } } ], "group": { "kind": "build", "isDefault": true } }, { "label": "clean", "type": "shell", "command": "make clean -f OBD_Simulatormake", "problemMatcher": [ "$gcc" ] } ] }
Hinweis: OBD_Simulatormake ist das vom Busmaster erzeugte Makefile für den Compiler und der Name muss an das eigene Simulations-Projekt angepasst werden.
<sxh [brush][; options]> ... code/text ... </sxh>
Beispiel mit Markierung bestimmter Zeilen:
#define CIRCBUF_DEF(x,y) uint8_t x##_space[y]; circBuf_t x = { x##_space,0,0,y} CIRCBUF_DEF(cb, 32); int circBufPush(circBuf_t *c, uint8_t data) { int next = c->head + 1; if (next >= c->maxLen) next = 0; // Cicular buffer is full if (next == c->tail) return -1; // quit with an error c->buffer[c->head] = data; c->head = next; return 0; } int circBufPop(circBuf_t *c, uint8_t *data) { int next; // if the head isn't ahead of the tail, we don't have any characters if (c->head == c->tail) return -1; // quit with an error *data = c->buffer[c->tail]; c->buffer[c->tail] = 0; // clear the data (optional) next = c->tail + 1; if(next >= c->maxLen) next = 0; c->tail = next; return 0; }
pi1_tipps
pi3_tipps
Upgrade von Rpi2 zu Rpi3 - System Upgrade von einer Rpi2 SD-Karte auf 3
I²C Schnittstelle und Raspi - Beispiele mit Python
Git: push over ssh:
cd my-project git remote add origin ssh://user@host/mnt/foo/bar/my-project.git git push origin master
Hier sind ein paar Links zu Eagle Libs für HW Erweiterungen für den Raspi
Mit diesem kleine Windowstool kann man die kompletter SD-Karte inkl. aller Partitionen klonen:
Hinweis: Eventuell muss man auf der Ziel SD-Karte vorher alle bestehende Partitioinen und das Volume mit dem Festplattenmanager löschen, falls es zu write Fehlern kommt (bei Roadkil's Diskimage war dies bei mir erforderlich)
Unter „Linux“ kann man auch „dd“ verwenden um die komplette SD-Karte oder einzelne Partitionen zu klonen.
# Ein Image von einer einzelnen Partion auf sdf erstellen: sudo dd if=/dev/sdf1 of=/home/myusername/raspberry_root-backup-sdf1-2017-05-10.img # komplettest Image erstellen: sudo dd if=/dev/sdf of=/home/myusername/raspberry-backup-sd_card_2017-05-10.img
Die obige erstellten Images können als „Loop Device“ eingebunden werden:
sudo losetup /dev/loop0 # prüfen, ob "loop0" frei ist (falls nichts erkannt wird ist es verfügbar.
sudo losetup /dev/loop0 /home/myusername/raspberry_root-backup-sdf1-2017-05-10.img #image dem loop device zuweisen
sudo mount -t vfat /dev/loop0 /media/sdimage-1 # image mounten, oder unter /mnt/raspi nachträglich als Read Only mounten: sudo mount -o remount,ro /mnt/raspi oder direkt als read only und wenn mehrere partitionen im image sind eine auswählen: sudo mount /dev/loop0p7 /mnt/raspi/ -o ro #read only und die Linux SystemPartition mounten
sudo umount /dev/loop0 sudo losetup -d /dev/loop0
obiges kann mit:
sudo losetup --find --show -P minix203.img
vereinfacht werden, da hier das Image direkt an das erste freie Loop-Device verbunden wird.
einzelne Fiterregeln (jails) kann man in der shell prüfen:
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf oder mit Ausgabe der Logzeile: fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf --print-all-matched
Hinweis: immer den kompletten Pfad zur Konfigurationsdatei verwenden
Fail2Ban Filter und Jails Konfiguration
Weitere Tipps:
fail2ban-client status fail2ban-client status ssh # zeigt alle IPs an die von "SSH" gebannt wurden fail2ban-client get ssh banned # gibt ein Array der gebannte IPs von "SSH" zurück fail2ban-client unban xxx.xxx.xxx.xx # IP für alle Jails wieder freigeben.
Hier eine kurze Beschreibung vom Modul:
ESP32-CAM Dev Board
Für meine Tests wurde die Version V4.2.1 verwendet. Mit der nachträglichen Installation des Signal Moduls:
pkg install D:\Downloads\chrome\signal-1.3.2.tar.gz
(signal-1.3.2.tar.gz, von Signal Package von Sourceforge)
danach muss das Modul noch mit:
pkg load signal
geladen werden.
Testfile bitte in *.m umbennenen fir_first_test.m
C:\Users\xxxBenutzernamexxx\AppData\Roaming\GitExtensions\GitExtensions\GitExtensions.settings
git submodule add ssh://andreas@geier99.de/opt/git/Projekte/Tools/diagLogger.git Andreas/diagLogger
Damit dies funktioniert, muss ein eventuell vorhandener Ordner „diagLogger“ aus dem Index erst gelöscht werden. Beim Pull wird dann auch das diaglogger geklont(oder gepullt)
Obiges Beispiel legt ein Submodul in ein bestehendes geklontes Git-Repository an (eventuell vorher den Ordner vom Submodul löschen)
Obiger Befehl legt auch die Datei .gitmodules an:
[submodule "Andreas/diagLogger"] path = Andreas/diagLogger url = ssh://andreas@geier99.de/opt/git/Projekte/Tools/diagLogger.git