убрала все про avr, проект собирается

This commit is contained in:
KLASSENTS 2025-03-19 13:20:54 +07:00
parent 2309d25142
commit a51abf17d1
8 changed files with 74 additions and 230 deletions

View File

@ -2,8 +2,14 @@
#include "Arduino.h"
// Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { }
int main()
{
initVariant(); // for freeRTOS
setup();
post_init();

View File

@ -24,6 +24,7 @@
#define INTERRUPT_AT_TOP (1 << OCIE0A)
extern "C"
// todo удалить файл?
void prvSetupTimerInterrupt( void )
{
// In case Arduino platform has pre-configured the timer,

View File

@ -91,7 +91,7 @@
#endif
#ifndef configUSE_MALLOC_FAILED_HOOK
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 1
#endif
/* Basic FreeRTOS definitions. */

View File

@ -29,7 +29,6 @@
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#include <avr/io.h>
/*-----------------------------------------------------------
* Application specific definitions.

View File

@ -26,9 +26,6 @@
#ifndef freeRTOSVariant_h
#define freeRTOSVariant_h
#include <avr/io.h>
#include <avr/wdt.h>
#ifndef INC_TASK_H
#include "Arduino_FreeRTOS.h"
#include "task.h"
@ -42,9 +39,9 @@ extern "C" {
// Use the Watchdog timer, and choose the rate at which scheduler interrupts will occur.
/* Watchdog Timer is 128kHz nominal, but 120 kHz at 5V DC and 25 degrees is actually more accurate, from data sheet. */
// todo удалить про watchdog?
#ifndef portUSE_WDTO
#define portUSE_WDTO WDTO_15MS // portUSE_WDTO to use the Watchdog Timer for xTaskIncrementTick
#define portUSE_WDTO /*WDTO_15MS*/ // portUSE_WDTO to use the Watchdog Timer for xTaskIncrementTick
#endif
/* Watchdog period options: WDTO_15MS
@ -58,9 +55,9 @@ extern "C" {
*/
#if defined( portUSE_WDTO )
#define configTICK_RATE_HZ ( (TickType_t)( (uint32_t)128000 >> (portUSE_WDTO + 11) ) ) // 2^11 = 2048 WDT scaler for 128kHz Timer
#define portTICK_PERIOD_MS ( (TickType_t) _BV( portUSE_WDTO + 4 ) )
// todo определить свое
#define configTICK_RATE_HZ /*( (TickType_t)( (uint32_t)128000 >> (portUSE_WDTO + 11) ) )*/ // 2^11 = 2048 WDT scaler for 128kHz Timer
#define portTICK_PERIOD_MS 1/*( (TickType_t) _BV( portUSE_WDTO + 4 ) )*/
#else
#warning "Variant configuration must define `configTICK_RATE_HZ` and `portTICK_PERIOD_MS` as either a macro or a constant"
#define configTICK_RATE_HZ 1

View File

@ -29,22 +29,19 @@
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include "Arduino_FreeRTOS.h"
#include "task.h"
/*-----------------------------------------------------------
* Implementation of functions defined in portable.h for the AVR port.
* Implementation of functions defined in portable.h
*----------------------------------------------------------*/
/* Start tasks with interrupts enabled. */
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
#if defined( portUSE_WDTO )
// todo подсунуть свое
#define portSCHEDULER_ISR WDT_vect
#else
@ -58,134 +55,6 @@
typedef void TCB_t;
extern volatile TCB_t * volatile pxCurrentTCB;
/*-----------------------------------------------------------*/
/**
* Enable the watchdog timer, configuring it for expire after
* (value) timeout (which is a combination of the WDP0
* through WDP3 bits).
*
* This function is derived from <avr/wdt.h> but enables only
* the interrupt bit (WDIE), rather than the reset bit (WDE).
*
* Can't find it documented but the WDT, once enabled,
* rolls over and fires a new interrupt each time.
*
* See also the symbolic constants WDTO_15MS et al.
*
* Updated to match avr-libc 2.0.0
*/
#if defined( portUSE_WDTO )
static __inline__
__attribute__ ((__always_inline__))
void wdt_interrupt_enable (const uint8_t value)
{
if (_SFR_IO_REG_P (_WD_CONTROL_REG))
{
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"wdr" "\n\t"
"out %0, %1" "\n\t"
"out __SREG__,__tmp_reg__" "\n\t"
"out %0, %2" "\n\t"
: /* no outputs */
: "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
"r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
_BV(WDIF) | _BV(WDIE) | (value & 0x07)) )
: "r0"
);
}
else
{
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"wdr" "\n\t"
"sts %0, %1" "\n\t"
"out __SREG__,__tmp_reg__" "\n\t"
"sts %0, %2" "\n\t"
: /* no outputs */
: "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
"r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
_BV(WDIF) | _BV(WDIE) | (value & 0x07)) )
: "r0"
);
}
}
#endif /* if defined( portUSE_WDTO ) */
/*-----------------------------------------------------------*/
/**
* Enable the watchdog timer, configuring it for expire after
* (value) timeout (which is a combination of the WDP0
* through WDP3 bits).
*
* This function is derived from <avr/wdt.h> but enables both
* the reset bit (WDE), and the interrupt bit (WDIE).
*
* This will ensure that if the interrupt is not serviced
* before the second timeout, the AVR will reset.
*
* Servicing the interrupt automatically clears it,
* and ensures the AVR does not reset.
*
* Can't find it documented but the WDT, once enabled,
* rolls over and fires a new interrupt each time.
*
* See also the symbolic constants WDTO_15MS et al.
*
* Updated to match avr-libc 2.0.0
*/
#if defined( portUSE_WDTO )
static __inline__
__attribute__ ((__always_inline__))
void wdt_interrupt_reset_enable (const uint8_t value)
{
if (_SFR_IO_REG_P (_WD_CONTROL_REG))
{
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"wdr" "\n\t"
"out %0, %1" "\n\t"
"out __SREG__,__tmp_reg__" "\n\t"
"out %0, %2" "\n\t"
: /* no outputs */
: "I" (_SFR_IO_ADDR(_WD_CONTROL_REG)),
"r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
_BV(WDIF) | _BV(WDIE) | _BV(WDE) | (value & 0x07)) )
: "r0"
);
}
else
{
__asm__ __volatile__ (
"in __tmp_reg__,__SREG__" "\n\t"
"cli" "\n\t"
"wdr" "\n\t"
"sts %0, %1" "\n\t"
"out __SREG__,__tmp_reg__" "\n\t"
"sts %0, %2" "\n\t"
: /* no outputs */
: "n" (_SFR_MEM_ADDR(_WD_CONTROL_REG)),
"r" ((uint8_t)(_BV(_WD_CHANGE_BIT) | _BV(WDE))),
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) |
_BV(WDIF) | _BV(WDIE) | _BV(WDE) | (value & 0x07)) )
: "r0"
);
}
}
#endif /* if defined( portUSE_WDTO ) */
/*-----------------------------------------------------------*/
/* actual number of ticks per second, after configuration. Not for RTC, which has 1 tick/second. */
TickType_t portTickRateHz;
@ -220,10 +89,11 @@ volatile TickType_t ticksRemainingInSec;
* The interrupts will have been disabled during the call to portSAVE_CONTEXT()
* so we need not worry about reading/writing to the stack pointer.
*/
// todo здесь что-то одно оставить и адаптировать под нас
#if defined(__AVR_3_BYTE_PC__) && defined(__AVR_HAVE_RAMPZ__)
/* 3-Byte PC Save with RAMPZ */
#define portSAVE_CONTEXT() \
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
/* __asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
"in __tmp_reg__, __SREG__ \n\t" \
"cli \n\t" \
"push __tmp_reg__ \n\t" \
@ -269,11 +139,11 @@ volatile TickType_t ticksRemainingInSec;
"st x+, __tmp_reg__ \n\t" \
"in __tmp_reg__, __SP_H__ \n\t" \
"st x+, __tmp_reg__ \n\t" \
);
);*/
#elif defined(__AVR_HAVE_RAMPZ__)
/* 2-Byte PC Save with RAMPZ */
#define portSAVE_CONTEXT() \
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
/* __asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
"in __tmp_reg__, __SREG__ \n\t" \
"cli \n\t" \
"push __tmp_reg__ \n\t" \
@ -317,11 +187,11 @@ volatile TickType_t ticksRemainingInSec;
"st x+, __tmp_reg__ \n\t" \
"in __tmp_reg__, __SP_H__ \n\t" \
"st x+, __tmp_reg__ \n\t" \
);
);*/
#else /* if defined( __AVR_3_BYTE_PC__ ) && defined( __AVR_HAVE_RAMPZ__ ) */
/* 2-Byte PC Save */
#define portSAVE_CONTEXT() \
__asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
/* __asm__ __volatile__ ( "push __tmp_reg__ \n\t" \
"in __tmp_reg__, __SREG__ \n\t" \
"cli \n\t" \
"push __tmp_reg__ \n\t" \
@ -363,17 +233,18 @@ volatile TickType_t ticksRemainingInSec;
"st x+, __tmp_reg__ \n\t" \
"in __tmp_reg__, __SP_H__ \n\t" \
"st x+, __tmp_reg__ \n\t" \
);
);*/
#endif /* if defined( __AVR_3_BYTE_PC__ ) && defined( __AVR_HAVE_RAMPZ__ ) */
/*
* Opposite to portSAVE_CONTEXT(). Interrupts will have been disabled during
* the context save so we can write to the stack pointer.
*/
// todo здесь что-то одно оставить и адаптировать под нас
#if defined(__AVR_3_BYTE_PC__) && defined(__AVR_HAVE_RAMPZ__)
/* 3-Byte PC Restore with RAMPZ */
#define portRESTORE_CONTEXT() \
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
/* __asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
"lds r27, pxCurrentTCB + 1 \n\t" \
"ld r28, x+ \n\t" \
"out __SP_L__, r28 \n\t" \
@ -417,11 +288,11 @@ volatile TickType_t ticksRemainingInSec;
"pop __tmp_reg__ \n\t" \
"out __SREG__, __tmp_reg__ \n\t" \
"pop __tmp_reg__ \n\t" \
);
);*/
#elif defined(__AVR_HAVE_RAMPZ__)
/* 2-Byte PC Restore with RAMPZ */
#define portRESTORE_CONTEXT() \
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
/* __asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
"lds r27, pxCurrentTCB + 1 \n\t" \
"ld r28, x+ \n\t" \
"out __SP_L__, r28 \n\t" \
@ -463,11 +334,11 @@ volatile TickType_t ticksRemainingInSec;
"pop __tmp_reg__ \n\t" \
"out __SREG__, __tmp_reg__ \n\t" \
"pop __tmp_reg__ \n\t" \
);
);*/
#else /* if defined( __AVR_3_BYTE_PC__ ) && defined( __AVR_HAVE_RAMPZ__ ) */
/* 2-Byte PC Restore */
#define portRESTORE_CONTEXT() \
__asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
/* __asm__ __volatile__ ( "lds r26, pxCurrentTCB \n\t" \
"lds r27, pxCurrentTCB + 1 \n\t" \
"ld r28, x+ \n\t" \
"out __SP_L__, r28 \n\t" \
@ -507,7 +378,7 @@ volatile TickType_t ticksRemainingInSec;
"pop __tmp_reg__ \n\t" \
"out __SREG__, __tmp_reg__ \n\t" \
"pop __tmp_reg__ \n\t" \
);
);*/
#endif /* if defined( __AVR_3_BYTE_PC__ ) && defined( __AVR_HAVE_RAMPZ__ ) */
/*-----------------------------------------------------------*/
@ -539,6 +410,7 @@ uint16_t usAddress;
*pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
pxTopOfStack--;
// todo проверить, что тут для нас нужно написать
#if defined(__AVR_3_BYTE_PC__)
/* The AVR ATmega2560/ATmega2561 have 256KBytes of program memory and a 17-bit
@ -624,8 +496,9 @@ void vPortEndScheduler( void )
{
/* It is unlikely that the ATmega port will get stopped. If required simply
* disable the tick interrupt here. */
wdt_disable(); /* disable Watchdog Timer */
// todo вставить свое
// wdt_disable(); /* disable Watchdog Timer */
}
/*-----------------------------------------------------------*/
@ -649,6 +522,7 @@ extern void delay ( unsigned long ms );
void vPortDelay( const uint32_t ms ) __attribute__ ( ( hot, flatten ) );
void vPortDelay( const uint32_t ms )
{
// todo проверить
if ( ms < portTICK_PERIOD_MS )
{
delay( (unsigned long) (ms) );
@ -692,7 +566,8 @@ void vPortYieldFromISR( void )
vTaskSwitchContext();
portRESTORE_CONTEXT();
__asm__ __volatile__ ( "reti" );
// todo что тут?
// __asm__ __volatile__ ( "reti" );
}
/*-----------------------------------------------------------*/
@ -718,6 +593,7 @@ void vPortYieldFromTick( void )
}
/*-----------------------------------------------------------*/
// todo прописать свое
#if defined( portUSE_WDTO )
/*
@ -726,10 +602,10 @@ void vPortYieldFromTick( void )
void prvSetupTimerInterrupt( void )
{
/* reset watchdog */
wdt_reset();
// wdt_reset();
/* set up WDT Interrupt (rather than the WDT Reset). */
wdt_interrupt_enable( portUSE_WDTO );
// wdt_interrupt_enable( portUSE_WDTO );
}
#else
@ -739,8 +615,8 @@ void vPortYieldFromTick( void )
/*-----------------------------------------------------------*/
// todo что тут?
#if configUSE_PREEMPTION == 1
/*
* Tick ISR for preemptive scheduler. We can use a naked attribute as
* the context is saved at the start of vPortYieldFromTick(). The tick
@ -749,15 +625,15 @@ void vPortYieldFromTick( void )
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
*
*/
ISR( portSCHEDULER_ISR, ISR_NAKED ) __attribute__ ( ( hot, flatten ) );
//ISR( portSCHEDULER_ISR, ISR_NAKED ) __attribute__ ( ( hot, flatten ) );
/* ISR( portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK ) __attribute__ ( ( hot, flatten ) );
*/
ISR( portSCHEDULER_ISR )
{
vPortYieldFromTick();
__asm__ __volatile__ ( "reti" );
}
// ISR( portSCHEDULER_ISR )
// {
// vPortYieldFromTick();
// __asm__ __volatile__ ( "reti" );
// }
#else /* if configUSE_PREEMPTION == 1 */
/*
@ -767,12 +643,12 @@ void vPortYieldFromTick( void )
*
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
*/
ISR( portSCHEDULER_ISR ) __attribute__ ( ( hot, flatten ) );
// ISR( portSCHEDULER_ISR ) __attribute__ ( ( hot, flatten ) );
/* ISR( portSCHEDULER_ISR, ISR_NOBLOCK ) __attribute__ ( ( hot, flatten ) );
*/
ISR( portSCHEDULER_ISR )
{
xTaskIncrementTick();
}
// ISR( portSCHEDULER_ISR )
// {
// xTaskIncrementTick();
// }
#endif /* if configUSE_PREEMPTION == 1 */

View File

@ -29,7 +29,6 @@
#ifndef PORTMACRO_H
#define PORTMACRO_H
#include <avr/wdt.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
@ -67,31 +66,31 @@ typedef uint8_t UBaseType_t;
/*-----------------------------------------------------------*/
/* Critical section management. */
// todo проверить
#define portENTER_CRITICAL() \
__asm__ __volatile__ ( \
/*__asm__ __volatile__ ( \
"in __tmp_reg__, __SREG__" "\n\t" \
"cli" "\n\t" \
"push __tmp_reg__" "\n\t" \
::: "memory" \
)
)*/
// todo проверить
#define portEXIT_CRITICAL() \
__asm__ __volatile__ ( \
/*__asm__ __volatile__ ( \
"pop __tmp_reg__" "\n\t" \
"out __SREG__, __tmp_reg__" "\n\t" \
::: "memory" \
)
)*/
#define portDISABLE_INTERRUPTS() __asm__ __volatile__ ( "cli" ::: "memory" )
#define portENABLE_INTERRUPTS() __asm__ __volatile__ ( "sei" ::: "memory" )
// todo проверить
#define portDISABLE_INTERRUPTS() /*__asm__ __volatile__ ( "cli" ::: "memory" )*/
#define portENABLE_INTERRUPTS() /*__asm__ __volatile__ ( "sei" ::: "memory" )*/
/*-----------------------------------------------------------*/
/* Architecture specifics. */
#define sleep_reset() do { _SLEEP_CONTROL_REG = 0; } while(0) /* reset all sleep_mode() configurations. */
// todo проверить
#define sleep_reset() /*do { _SLEEP_CONTROL_REG = 0; } while(0)*/ /* reset all sleep_mode() configurations. */
#define portSTACK_GROWTH ( -1 )
#define portBYTE_ALIGNMENT 1

View File

@ -24,11 +24,6 @@
*/
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <util/delay.h>
#include <Arduino.h>
@ -46,15 +41,13 @@ void initVariant(void) __attribute__ ((OS_main));
void initVariant(void)
{
// As the Task stacks are on heap before Task allocated heap variables,
// the library default __malloc_heap_end = 0 doesn't work.
__malloc_heap_end = (char *)(RAMEND - __malloc_margin);
#if defined(USBCON)
USBDevice.attach();
#endif
// todo что с этим?
// // As the Task stacks are on heap before Task allocated heap variables,
// // the library default __malloc_heap_end = 0 doesn't work.
// __malloc_heap_end = (char *)(RAMEND - __malloc_margin);
setup(); // the normal Arduino setup() function is run here.
post_init();
vTaskStartScheduler(); // initialise and run the freeRTOS scheduler. Execution should never return here.
}
@ -74,7 +67,6 @@ void vApplicationIdleHook( void ) __attribute__ ((weak));
void vApplicationIdleHook( void )
{
loop(); // the normal Arduino loop() function is run here.
if (serialEventRun) serialEventRun();
}
#else
@ -89,25 +81,10 @@ void vApplicationIdleHook( void )
*/
void prvSetMainLedOn( void )
{
#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) // Arduino Mega with 2560
DDRB |= _BV(DDB7);
PORTB |= _BV(PORTB7); // Main (red PB7) LED on. Main LED on.
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284PA__) // Seeed Goldilocks with 1284p
DDRB |= _BV(DDB7);
PORTB |= _BV(PORTB7); // Main (red PB7) LED on. Main LED on.
#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) // assume we're using an Arduino Uno with 328p
DDRB |= _BV(DDB5);
PORTB |= _BV(PORTB5); // Main (red PB5) LED on. Main LED on.
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) // assume we're using an Arduino Leonardo with 32u4
DDRC |= _BV(DDC7);
PORTC |= _BV(PORTC7); // Main (red PC7) LED on. Main LED on.
#if defined (LED_BUILTIN)
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
#endif
}
/**
@ -115,19 +92,8 @@ void prvSetMainLedOn( void )
*/
void prvBlinkMainLed( void )
{
#if defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega2561__) // Mega with 2560
PINB |= _BV(PINB7); // Main (red PB7) LED toggle.
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284PA__) // Seeed Goldilocks with 1284p
PINB |= _BV(PINB7); // Main (red PB7) LED toggle.
#elif defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) || defined(__AVR_ATmega8__) // assume we're using an Arduino Uno with 328p
PINB |= _BV(PINB5); // Main (red PB5) LED toggle.
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__) // assume we're using an Arduino Leonardo with 32u4
PINC |= _BV(PINC7); // Main (red PC7) LED toggle.
#if defined (LED_BUILTIN)
digitalToggle(LED_BUILTIN);
#endif
}
@ -158,7 +124,7 @@ void vApplicationMallocFailedHook( void )
for(;;)
{
_delay_ms(50);
// _delay_ms(50); // todo это что за функция?
prvBlinkMainLed(); // Main LED fast blink.
}
}
@ -180,7 +146,7 @@ void vApplicationStackOverflowHook( TaskHandle_t xTask __attribute__ ((unused)),
for(;;)
{
_delay_ms(2000);
// _delay_ms(2000);
prvBlinkMainLed(); // Main LED slow blink.
}
}