реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Запись во FLASH, STM32F303VC
Jenya7
сообщение Feb 19 2018, 09:09
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Я пишу во флеш полусловами (uint16_t), как и положено
Код
FLASH_Status WriteFlash(void* src, void* dst, int len)
{
    uint16_t* srcw = (uint16_t*)src;
    volatile uint16_t* dstw = (uint16_t*)dst;

    FLASH_Status status = FLASH_COMPLETE;
    
    FLASH->CR |= FLASH_CR_PG; /* Programm the flash */
    
    while (len)
    {
    *dstw = *srcw;
    while ((FLASH->SR & FLASH_SR_BSY) != 0 )
        
        
    if (*dstw != *srcw )
    {
             status = FLASH_ERROR_PROGRAM;
             break;
    }
    dstw++;
    srcw++;
    //len = len - sizeof(uint16_t);
        len--;
    }
    
    FLASH->CR &= ~FLASH_CR_PG; /* Reset the flag back !!!! */
    
    return status;
}


допустим пишу структуру
Код
typedef struct G_MOTOR_DATA_S
{
    uint8_t debug;
    uint8_t service;
    uint8_t current_mot_num;
    uint8_t storage;
    
    uint32_t max_pos_diff;
    uint32_t max_pos_diff_count;
    uint32_t pwm_min;
    uint32_t pwm_max;
    uint32_t pwm_delta;
    uint32_t max_stabdel;
    
    //run_time
    uint32_t pos_diff_count;
    uint32_t stabdel_count;
    
} GLOB_MOTOR_DATA;

#define GLOB_MOTOR_DATA_HALF_WORD_CNT  18

соответственно размер в uint16_t - 18.
тестирую
Код
glob_mot_data.debug = 0x01;
    glob_mot_data.service = 0x01;
    glob_mot_data.current_mot_num = 0x02;
    glob_mot_data.storage = 0x02;
    
    glob_mot_data.max_pos_diff = 0xAA;
    glob_mot_data.max_pos_diff_count = 0xAA;
    glob_mot_data.pwm_min = 0xBB;
    glob_mot_data.pwm_max = 0xBB;
    glob_mot_data.pwm_delta = 0xCC;
    glob_mot_data.max_stabdel = 0xCC;
    
    size = GLOB_MOTOR_DATA_HALF_WORD_CNT;
    addr = (uint32_t *)(flash_page + offset);
    status = WriteFlash(&glob_mot_data, addr, size);

смотрим в память и что мы видим (на картинке)? растояние между полями не uint32_t а два uint32_t. как так?

категорически извиняюсь. моя ошибка. неправильно посчитал.

Сообщение отредактировал Jenya7 - Feb 19 2018, 10:12
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
arhiv6
сообщение Feb 19 2018, 09:44
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423



Где вы тут два uint32_t увидели? 0x00 0x00 0x00 0xCC - это 4 байта, 4 байта*8 бит=32 бита. Что не так?

И ещё, если вы дефайном GLOB_MOTOR_DATA_HALF_WORD_CNT задаёте размер структуры, то это неправильно, компилятор может при желании выделить всем полям по 4 байта, в том числе и для uint8_t. Вот подробнее.


--------------------
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 19 2018, 10:01
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(arhiv6 @ Feb 19 2018, 14:44) *
Где вы тут два uint32_t увидели? 0x00 0x00 0x00 0xCC - это 4 байта, 4 байта*8 бит=32 бита. Что не так?

И ещё, если вы дефайном GLOB_MOTOR_DATA_HALF_WORD_CNT задаёте размер структуры, то это неправильно, компилятор может при желании выделить всем полям по 4 байта, в том числе и для uint8_t. Вот подробнее.

глаз замылился. долго тупил в экран, стал считать лишние байты.
я бы с удовольствием сделал без привязки к размеру - вместо while (len) сделать while (*srcw) но так нельзя. если только последним членом в структуре вставить какой нибудь терминатор '\0'.

я слежу чтоб все структуры были /4.

Сообщение отредактировал Jenya7 - Feb 19 2018, 10:10
Go to the top of the page
 
+Quote Post
arhiv6
сообщение Feb 19 2018, 10:21
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423



Цитата(Jenya7 @ Feb 19 2018, 17:01) *
я бы с удовольствием сделал без привязки к размеру - вместо while (len) сделать while (*srcw) но так нельзя. если только последним членом в структуре вставить какой нибудь терминатор '\0'.

Или используйте #pragma pack, чтобы компилятор паковал структуру без "пробелов", или, что ещё лучше в вашем случае - избавьтесь от магической константы 18, пусть компилятор сам этот размер высчитывает: вместо
Код
#define GLOB_MOTOR_DATA_HALF_WORD_CNT  18
пишите
Код
#define GLOB_MOTOR_DATA_HALF_WORD_CNT (sizeof(G_MOTOR_DATA_S))


--------------------
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 19 2018, 10:33
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(arhiv6 @ Feb 19 2018, 15:21) *
Или используйте #pragma pack, чтобы компилятор паковал структуру без "пробелов", или, что ещё лучше в вашем случае - избавьтесь от магической константы 18, пусть компилятор сам этот размер высчитывает: вместо
Код
#define GLOB_MOTOR_DATA_HALF_WORD_CNT  18
пишите
Код
#define GLOB_MOTOR_DATA_HALF_WORD_CNT (sizeof(G_MOTOR_DATA_S))

sizeof высчитывается в uint8_t а я записываю во флеш в uint16_t. при подстановке в WriteFlash(&glob_mot_data, addr, size); я передаю размер в uint16_t, так это определено - писать не байтами а uint16_t.

ааа. если я верну len = len - sizeof(uint16_t); я могу передать передать размер в байтах в качестве аргумента?

Сообщение отредактировал Jenya7 - Feb 19 2018, 10:37
Go to the top of the page
 
+Quote Post
arhiv6
сообщение Feb 19 2018, 10:44
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 633
Регистрация: 21-05-10
Из: Томск
Пользователь №: 57 423



Так Вы в функцию FLASH_Status WriteFlash(void* src, void* dst, int len) передавайте размер в байтах, а внутри неё на флешку пишите по два байта.


--------------------
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 19 2018, 10:49
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(arhiv6 @ Feb 19 2018, 15:44) *
Так Вы в функцию FLASH_Status WriteFlash(void* src, void* dst, int len) передавайте размер в байтах, а внутри неё на флешку пишите по два байта.

так я так и делаю - привожу к (uint16_t*) - но тогда соответственно нужно и размер уменьшать пропорционально len -= sizeof(uint16_t); у меня сейчас len--;

да. точно. спасибо. наконец устаканилось в голове.

раз пошла такая пьянка может мы решим проблему переполнения страницы? одним топиком двух зайчиков чпокнем.

Сообщение отредактировал Jenya7 - Feb 19 2018, 11:04
Go to the top of the page
 
+Quote Post
x893
сообщение Feb 19 2018, 11:55
Сообщение #8


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Боже мой.
Это же офигенная проблема.
Как же мы будем её решать ?
Только коллективным разумом будем сравнивать длину с размером страницы и записывать минимальное из этих чисел и передвигать указать на записанное количество и потом её же вычитать из длины и сравнивать её с нулем.
Хотя нет - это путь простой и не подходит гуру программирования.
Будем дисскутировать и делать череж ж...

Вот такой план есть - пойдет ?
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Feb 19 2018, 12:02
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата
Только коллективным разумом будем сравнивать длину с размером страницы и записывать минимальное из этих чисел и передвигать указать на записанное количество и потом её же вычитать из длины и сравнивать её с нулем.

я хочу обойтись минимальным количеством аргументов. только текущий адрес.

как бы можно и так
Код
uint32_t SpaceLeft(uint32_t page, uint32_t addr, uint32_t size, uint32_t *overflow)
{
    *overflow = 0;
    uint32_t end_of_page = (page + FLASH_PAGE_SIZE) - 1;
    
    if ((addr + size) > end_of_page)
        *overflow = 1;
    
    return  end_of_page - addr;
}

но мне не нравиться. куча аргументов.

Сообщение отредактировал Jenya7 - Feb 19 2018, 12:11
Go to the top of the page
 
+Quote Post
x893
сообщение Feb 19 2018, 16:23
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



Сложно мне сказать, так не понимаю всё глубину полёта мысли.
По мне так сделать функцию с параметрами

указатель на данные
кол-во байт для записи
адрес куда писать

И возвращать false если нет ошибки и true если жизнь не удалась и сохранить не удалось.

А в ней уже проявлять мастерство программирования.
Go to the top of the page
 
+Quote Post
картошка
сообщение Feb 21 2018, 12:48
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 65
Регистрация: 28-12-05
Из: Odessa
Пользователь №: 12 673



Думаю что в тему. Чтоб не парится с прагмапаками, прагмапушами и прагмапопами или аналогичными вещами - нужно усвоить архизнаниё ! wink.gif .

Все базовые (интежер) типы данных компиляторы размещают по адресам кратным их размерности (это для 16 битных и 32 битных компиляторов). При создании структур желательно не микшировать подряд и в праполую char, short и long.
Настоятельно рекомендую сортировать в типовом порядке от 4 байтных - до 1 байтных, Причём при переходе типов самостоятельно дополнять нужными полями нужной размерности.
Пример создания структуры состоящей из фиксированного набора параметров, например три 4 байтных, два 2 байтных и одного однобайтного:

Хорошо:------------------Не хорошо------------------------------------Не хорошо
long------------------------char------------------------------------------- short
long------------------------short (впереди выравнивание + 1)-------- long (впереди выравнивание + 2)
long------------------------long------------------------------------------- short
short-----------------------long-------------------------------------------- long (впереди выравнивание + 2)
short-----------------------long-------------------------------------------- char
char------------------------short------------------------------------------- long (впереди выравнивание + 3)
-----------------------------------------------------------------------------------------------------------------------------
17 байт--------------------18 байт-----------------------------------------24 байт

В случае примеров "не хорошо" - дополнять руками какими нибудь типовыми полями по нужной размерности sm.gif, чтоб компилятор не делал это за вас.

Сообщение отредактировал картошка - Feb 21 2018, 12:53
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 09:03
Рейтинг@Mail.ru


Страница сгенерированна за 0.01447 секунд с 7
ELECTRONIX ©2004-2016