ну надо было передать циклу в качестве значения. Или не надо?NStorm писал(а):И зачем? Зачем под это тратить память, когда размер строки во флэше всё-равно неизменен всегда?
Код: Выделить всё
for (i = 0; i < (strlegn-1); i ++)
{}
ну надо было передать циклу в качестве значения. Или не надо?NStorm писал(а):И зачем? Зачем под это тратить память, когда размер строки во флэше всё-равно неизменен всегда?
Код: Выделить всё
for (i = 0; i < (strlegn-1); i ++)
{}
Код: Выделить всё
for (i = 0; i < (MY_STRING_LEN-1); i ++)
Код: Выделить всё
for (i = 0; i < (sizeof(lcd_data)-1); i ++)
в микроконтроллерном программировании практически всегда совершенно все равно, какой тип у функции main, поскольку эта функция никуда результат своей работы не возвращает - некуда просто.Shuspano писал(а):Какой тип она имеет, если это явно не указано?
во многих случаях именно не надо.Shuspano писал(а):ну надо было передать циклу в качестве значения. Или не надо?
Код: Выделить всё
void my_func(char *s){
while(*s){
// тут обрабатываем очередной символ *s
s++; // и берем следующий символ
}
}Код: Выделить всё
void my_func(const __flash char *s){
while(*s){
// тут обрабатываем очередной символ *s
s++; // и берем следующий символ
}
}Код: Выделить всё
void my_func(const __memx char *s){
while(*s){
// тут обрабатываем очередной символ *s
s++; // и берем следующий символ
}
}я так понимаю, в юникоде не надо умничать, а надо пользоваться библиотечными функциями/классами поддержки юникода, и веселье будет отменено.ПростоНуб писал(а):самое веселое начинается в юникоде
Код: Выделить всё
#ifndef EEPROM_H_
#define EEPROM_H_
#define EEPROM_TOUCH_ADDRESS 0
/* Настройки тач панели дисплея */
float touch_factor_x;
float touch_factor_y;
int touch_term_x;
int touch_term_y;
#endif /* EEPROM_H_ */Код: Выделить всё
#include <avr/eeprom.h>
#include "config.h"
/* Настройки тач панели дисплея */
float EEMEM touch_factor_x;
float EEMEM touch_factor_y;
int EEMEM touch_term_x;
int EEMEM touch_term_y;/**/Код: Выделить всё
float factor_x, factor_y;
int term_x, term_y;
...
...
//uint16_t addr = EEPROM_TOUCH_ADDRESS;
//factor_x = eeprom_read_float((float *) addr);
//addr += sizeof(factor_x);
//factor_y = eeprom_read_float((float *) addr);
//addr += sizeof(factor_y);
//term_x = eeprom_read_word((uint16_t *) addr);
//addr += sizeof(term_x);
//term_y = eeprom_read_word((uint16_t *) addr);
factor_x = eeprom_read_float((float *) &touch_factor_x);
factor_y = eeprom_read_float((float *) &touch_factor_y);
term_x = eeprom_read_word((uint16_t *) &touch_term_x);
term_y = eeprom_read_word((uint16_t *) &touch_term_y);
if(term_x == -1 && term_y == -1) touch_calibrated = 0;после того, как все настройки считаны в ОЗУ в структуру config, вы в любой момент можете обращаться к её куску config.someone - в чем проблема?MOHCTEP писал(а):настройки потребуются "кусками" в непредсказуемые периоды времени
на здоровье: в той же структуре обновляйте config.someone когда угодно и сколько угодно раз!MOHCTEP писал(а):обновляться тоже кусочно будут
зачем?! только в критические моменты: при (перед) выключении питания или в моменты простоя (раз в 1...100 секунд, например). для чего после каждого чиха обновлять настройки?!MOHCTEP писал(а):всю эту кучу надо будет перезаписывать, при малейшем изменении?
да, сверит все и обновит только те байты, которые изменились. потому она и updateMOHCTEP писал(а):И "eeprom_update_block" обновит только изменившиеся данные
Код: Выделить всё
#define EEPROM_SIZE 512
#define EEPROM_ENTRY_SIZE (sizeof(settings_t) + sizeof(state_t))
#define EEPROM_ENTRIES (EEPROM_SIZE / EEPROM_ENTRY_SIZE)
typedef struct {
uint32_t seq;
// state_t goes here in actual EEPROM
uint16_t crc;
} settings_t;
void load_settings() {
uint8_t *ptr = 0; // byte pointer in EEPROM
uint32_t cur_seq = 0;
state_t state_buf;
cli();
while (queue_num < EEPROM_ENTRIES) {
settings.seq = eeprom_read_dword((void *) ptr);
if (settings.seq <= cur_seq || settings.seq == 0xFFFFFFFF) {
settings.seq = cur_seq;
break;
}
cur_seq = settings.seq;
ptr += sizeof (settings.seq);
eeprom_read_block(&state_buf, (void *) ptr, sizeof (state_buf));
ptr += sizeof (state_buf);
settings.crc = eeprom_read_word((void *) ptr);
ptr += sizeof (settings.crc);
if (settings.crc != crc16((void *) &state_buf, sizeof (state_buf))) {
LOG("CRC incorrect\r\n");
break;
}
// Since we are here, settings are valid, CRC are good
state = state_buf;
queue_num++;
}
sei();
}
void save_settings(eSaveMode savemode) {
cli();
settings.crc = crc16((void *) &state, sizeof (state)); // Calculate crc16 of state struct
// Save data to EEPROM
settings.seq++;
if (queue_num >= EEPROM_ENTRIES) // Reset queue_num once we reach end of EEPROM
queue_num = 0;
uint8_t *ptr = (void *)(queue_num * EEPROM_ENTRY_SIZE); // Get location of next segment in EEPROM
eeprom_write_dword((void *) ptr, settings.seq);
ptr += sizeof (settings.seq);
eeprom_update_block((void *)&state, (void *) ptr, sizeof (state));
ptr += sizeof (state);
eeprom_write_word((void *) ptr, settings.crc);
sei();
}
Так в чем проблема? Делаете из них структуру и сохраняете, как выше писали. Структуры тоже вполне можно включать в структуры. Строки, если фиксированной максимальной длины - вообще без проблем.Ступор у меня в том, что разнообразие настроек довольно велико и они тоже разные: от 32 битных, до бит-полей, есть и структуры и массивы, возможны и строки. Вот как весь этот винегрет увязать в структуру и подружить ее с EEPROM?