Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
1

SAM3X write flash

20.01.2020, 16:39. Просмотров 1399. Ответов 14
Метки нет (Все метки)

Не могу разобраться в примере atmel studio по записи данных в флешь память.
Здесь контроллер получает команду стереть страницу и записать новые данные на эту страницу памяти, а вот откуда он берёт адрес памяти откуда нужно брать данные, я так и не понял? Подскажите пожалуйста!
EEFC_FCR_FARG(us_page) - на какую страницу флеш памяти записать данные
C
1
2
EFC1->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(us_page) | EEFC_FCR_FCMD(EFC_FCMD_EWP);
//efc_perform_command(p_efc, EFC_FCMD_EWP, us_page);
Вот пример от атмел студио
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/**
 * \brief Write a data buffer on flash.
 *
 * \note This function works in polling mode, and thus only returns when the
 * data has been effectively written.
 * \note For dual bank flash, this function doesn't support cross write from
 * bank 0 to bank 1. In this case, flash_write must be called twice (ie for
 * each bank).
 *
 * \param ul_address Write address.
 * \param p_buffer Data buffer.
 * \param ul_size Size of data buffer in bytes.
 * \param ul_erase_flag Flag to set if erase first.
 *
 * \return 0 if successful, otherwise returns an error code.
 */
uint32_t flash_write(uint32_t ul_address, const void *p_buffer,
        uint32_t ul_size, uint32_t ul_erase_flag)
{
    Efc *p_efc;
    uint32_t ul_fws_temp;
    uint16_t us_page;
    uint16_t us_offset;
    uint32_t writeSize;
    uint32_t ul_page_addr;
    uint16_t us_padding;
    uint32_t ul_error;
    uint32_t ul_idx;
    uint32_t *p_aligned_dest;
    uint8_t *puc_page_buffer = (uint8_t *) gs_ul_page_buffer;
 
    translate_address(&p_efc, ul_address, &us_page, &us_offset);
 
#if SAM3S || SAM3N || SAM3XA || SAM3U
    /* According to the errata, set the wait state value to 6. */
    ul_fws_temp = efc_get_wait_state(p_efc);
    efc_set_wait_state(p_efc, 6);
#else
    UNUSED(ul_fws_temp);
#endif
 
    /* Write all pages */
    while (ul_size > 0) {
        /* Copy data in temporary buffer to avoid alignment problems. */
        writeSize = Min((uint32_t) IFLASH_PAGE_SIZE - us_offset,
                ul_size);
        compute_address(p_efc, us_page, 0, &ul_page_addr);
        us_padding = IFLASH_PAGE_SIZE - us_offset - writeSize;
 
        /* Pre-buffer data */
        memcpy(puc_page_buffer, (void *)ul_page_addr, us_offset);
 
        /* Buffer data */
        memcpy(puc_page_buffer + us_offset, p_buffer, writeSize);
 
        /* Post-buffer data */
        memcpy(puc_page_buffer + us_offset + writeSize,
                (void *)(ul_page_addr + us_offset + writeSize),
                us_padding);
 
        /* Write page.
         * Writing 8-bit and 16-bit data is not allowed and may lead to
         * unpredictable data corruption.
         */
        p_aligned_dest = (uint32_t *) ul_page_addr;
        for (ul_idx = 0; ul_idx < (IFLASH_PAGE_SIZE / sizeof(uint32_t));
                ++ul_idx) {
            *p_aligned_dest++ = gs_ul_page_buffer[ul_idx];
        }
 
        ul_error = efc_perform_command(p_efc, EFC_FCMD_EWP, us_page); //EFC1->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(us_page) | EEFC_FCR_FCMD(EFC_FCMD_EWP)  
        
        if (ul_error) {
            return ul_error;
        }
 
        /* Progression */
        p_buffer = (void *)((uint32_t) p_buffer + writeSize);
        ul_size -= writeSize;
        us_page++;
        us_offset = 0;
    }
 
#if SAM3S || SAM3N || SAM3XA || SAM3U
    /* According to the errata, restore the wait state value. */
    efc_set_wait_state(p_efc, ul_fws_temp);
#endif
 
    return FLASH_RC_OK;
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
20.01.2020, 16:39
Ответы с готовыми решениями:

AS-sam3X. Зажечь светодиод через веб-интерфейс
Здравствуйте. Нужно зажечь и потушить светодиод на плате AS-sam3X через веб-интерфейс, подключив...

Error: "Flash is write-protected".Может посоветуете, как снять защиту?
Здравствуйте.Пробовал прошить прошивальщиком AMIFLASH V8.95. Выходит сообщение -&quot;Flash is...

Ошибка cannot write a property that has no write specifiers
TTabItem* newtab; newtab = new TTabItem(this); newtab-&gt;TabControl = TabControl1; //Тут ошибка...

Добавить немного RAM в AVR SAM3X 32-bit (Arduino Due)
У меня есть контроллер AVR SAM3X 32-bit 86MHz. В моем проекте мне не хватает ОЗУ, хочу...

14
1792 / 1122 / 109
Регистрация: 04.01.2010
Сообщений: 3,955
20.01.2020, 18:11 2
Цитата Сообщение от Korbofos Посмотреть сообщение
откуда он берёт адрес памяти откуда нужно брать данные
вот это:
Цитата Сообщение от Korbofos Посмотреть сообщение
\param p_buffer Data buffer.
0
Модератор
Эксперт по электронике
8263 / 6123 / 820
Регистрация: 14.02.2011
Сообщений: 21,264
20.01.2020, 19:34 3
Цитата Сообщение от Korbofos Посмотреть сообщение
от атмел студио
как связана с Микроконтроллеры ARM, Cortex, STM32

Добавлено через 3 минуты
вопрос снимается
Цитата Сообщение от Korbofos Посмотреть сообщение
SAM3X
ARM Cortex-M3 revision 2.0 running at up to 84 MHz
0
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
24.01.2020, 05:40  [ТС] 4
p_buffer Да, но дальше не пойму где контроллеру указывается откуда данные брать для записи в память.
0
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
24.01.2020, 12:12  [ТС] 5
C++
1
2
3
/* Flash page buffer for alignment */
static uint32_t gs_ul_page_buffer[IFLASH_PAGE_SIZE / sizeof(uint32_t)];
uint8_t *puc_page_buffer = (uint8_t *) gs_ul_page_buffer;
копирует данные в массив gs_ul_page_buffer и дальше что? Не указывает контроллеру на этот массив никаким образом

Добавлено через 2 минуты
C++
1
2
3
4
5
6
7
8
9
memcpy(puc_page_buffer, (void *)ul_page_addr, us_offset);
 
        /* Buffer data */
        memcpy(puc_page_buffer + us_offset, p_buffer, writeSize);
 
        /* Post-buffer data */
        memcpy(puc_page_buffer + us_offset + writeSize,
                (void *)(ul_page_addr + us_offset + writeSize),
                us_padding);
0
1792 / 1122 / 109
Регистрация: 04.01.2010
Сообщений: 3,955
24.01.2020, 15:06 6
...копирует в "gs_ul_page_buffer", а затем пишет из него 32битными порциями в "p_aligned_dest". Это сделано, возможно, чтобы обеспечить гарантированно правильный код для копирования, средствами gcc (или чем-то еще). потому что правила доступа к ячейкам памяти могут отличаться от архитектуры, равно как и методы их копирования (как следствие).
1
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
26.01.2020, 05:08  [ТС] 7
Контроллеру ни где не указывается что нужно брать именно из этой области оперативной памяти и записать во флэш память.
0
2678 / 1198 / 160
Регистрация: 28.10.2011
Сообщений: 4,323
Записей в блоге: 6
26.01.2020, 17:17 8
Адреса указываются при вызове функции.
Цитата Сообщение от Korbofos Посмотреть сообщение
 * \param ul_address Write address.
 * \param p_buffer Data buffer.
 * \param ul_size Size of data buffer in bytes.
 * \param ul_erase_flag Flag to set if erase first.
0
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
28.01.2020, 06:52  [ТС] 9
А где контроллеру указывается что брать данные нужно именно из этой из этой области памяти* \param p_buffer Data buffer.
Хоть какой нибудь регистр, допустим как в этом примере.
C++
1
2
3
4
uint8_t txBuff[BUFF_SIZE];
PDC_USART1->PERIPH_RCR  = BUFF_SIZE;
PDC_USART1->PERIPH_TPR  = (uint32_t)txBuff; //указываем контроллеру на массив
PDC_USART1->PERIPH_TCR = len;
А в работе с флеш памятью таких регистров нет
0
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
28.01.2020, 06:56  [ТС] 10
вот регистры
0
Миниатюры
SAM3X write flash  
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
28.01.2020, 07:00  [ТС] 11
посмотреть примеры на stm32
0
1792 / 1122 / 109
Регистрация: 04.01.2010
Сообщений: 3,955
28.01.2020, 13:17 12
Korbofos, сначала из "p_buffer" функция копирует данные в свой буфер, по выравненному адресу. Затем сразу пишет во FLASH по адресу ячеек. Все выглядит как копирование, но по факту это не копирование, а запись.

PS: драйверы памяти FLASH (как и сама память) у производителей сильно отличаются. На платформе, которую вы рассматриваете, это один из самых простых (с т/з пользователя) вариантов, которые я встречал.
0
2678 / 1198 / 160
Регистрация: 28.10.2011
Сообщений: 4,323
Записей в блоге: 6
28.01.2020, 14:01 13
Цитата Сообщение от Korbofos Посмотреть сообщение
А в работе с флеш памятью таких регистров нет
Потому что пишет не в регистры, а непосредственно по заданному адресу, т. е. в память.
1
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
28.01.2020, 15:53  [ТС] 14
Спасибо парни, это указатель p_aligned_dest на память куда происходит запись, сразу не понял
0
5 / 5 / 1
Регистрация: 15.08.2011
Сообщений: 216
19.02.2020, 23:33  [ТС] 15
Лучший ответ Сообщение было отмечено ValeryS как решение

Решение

Кому пригодиться может, запись на последнюю страничку памяти
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#define PAGE_ADDRESS  (IFLASH1_ADDR + IFLASH1_SIZE - IFLASH1_PAGE_SIZE)
#define FLASH_ACCESS_MODE_128 0
#define EEFC_FCR_FCMD(value) ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
#define EFC_FCMD_WP      0x01  //!< Write page
#define EFC_FCMD_EWP     0x03  //!< Erase page and write page
#define EFC_FCMD_SLB     0x08  //!< Set Lock Bit
#define EFC_FCMD_CLB     0x09  //!< Clear Lock Bit
#define EFC_FCMD_SGPB    0x0B  //!< Set GPNVM Bit
#define EFC_FCMD_GGPB    0x0D  //!< Get GPNVM Bit
 
 
void Flash::write(uint32_t address, uint8_t *buf, uint16_t len)
{
 uint8_t i;
 uint32_t *pFlash = (uint32_t *) address;
 EFC1->EEFC_FMR = EEFC_FMR_FWS(6);                                                         //init flash
 EFC1->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(960) | EEFC_FCR_FCMD(EFC_FCMD_CLB); //Flash unlock
 for(i = 0; i < len; i++)                                                                      
    {
     *pFlash++ = *buf++;    
    }
 EFC1->EEFC_FCR = EEFC_FCR_FKEY_PASSWD | EEFC_FCR_FARG(1023) | EEFC_FCR_FCMD(EFC_FCMD_EWP); //write
 while (!(EFC1->EEFC_FSR & EEFC_FSR_FRDY));                                                 //wite
}
 
 
uint32_t Flash::read(uint32_t address) 
{
 uint32_t *pFlash = (uint32_t *) address;
 return *pFlash;
}
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.02.2020, 23:33

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

В чём различие write() и write(' ')
В чём различие?: write(); write(' ');

Serialport.write и serialport.basestream.write - в чем разница
в чем разница между следующими способами отправки данных на ком-порт?:...

Upload и Write to file failed. Ошибка: ADODB.Stream error '800a0bbc' Write to file failed.
Проблема вот в чем. Есть 3 компонента, и в админе каждого есть возможность загрузки файлов....

Candy Invensys - Flash KD60DA03E, Нужен Flash, для сравнения
Вечер добрый ! Нужен Флэш версии : KD60DA03E. Стиральная машина (фронталка) с сушкой, к сожалению...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.