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

 
 
> Редактирование данных в памяти программ.
koT-34
сообщение Mar 29 2010, 10:25
Сообщение #1





Группа: Участник
Сообщений: 6
Регистрация: 20-03-06
Пользователь №: 15 391



Добрый день.

Пишу на С, компилятор winavr, контроллер atmega64.
Знаю, что создать и прочитать переменные, в памяти программ, можно с помощью PROGMEM.

Возможно ли средствами С редактировать данные записанные во флеш память МК ?

Пример(создаю в памяти программ массив данных, и хочу изменить первый байт):

Код
static unsigned char mydata[20] PROGMEM = {0x00,0x01,0x02, ... 0x12,0x13,0x14};

Код
unsigned char temp = 10;
mydata[0] = temp;


Приведенный способ естественно не работает: error: assignment of read-only location 'mydata[0]'
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
jackkum
сообщение Sep 20 2011, 07:23
Сообщение #2





Группа: Новичок
Сообщений: 2
Регистрация: 20-09-11
Пользователь №: 67 287



Помогите пожалуйста, устал уже 2 дня бродить по инету ничего не могу найти sad.gif
Пишу бутлоадер на AVR Studio 5.0 для меги88 хекс генериться нормально, начинается с адреса 0x0E00 запускается тоже нормально, но при записи во флеш ничего не происходит, скачиваю всю флешь, загрузчик есть а новой прошивки нет, должна запасаться из еепрома внешнего по i2c во флеш с адреса 0x0000

Код
#define F_CPU 14745600
#define BOOTSIZE 512
#define APP_END (FLASHEND - (BOOTSIZE * 2))

#include <avr/io.h>
#include <avr/boot.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <stdio.h>
#include <string.h>

#include "i2c_eeprom.h"

uint8_t gBuffer[32];

uint16_t get_hex(uint8_t b){
    uint16_t hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}, x = 0;
    for(x = 0; x < sizeof(hex); x++){
        if(b == hex[x]){
            return x;
        }
    }
    return 0;
}

void eraseFlash(void)
{
    // erase only main section (bootloader protection)
    uint32_t addr = 0;
    
    boot_spm_busy_wait();
    
    while (APP_END > addr)
        {
        boot_page_erase(addr);        // Perform page erase
        boot_spm_busy_wait();        // Wait until the memory is erased.
        addr += 32;
        }
    boot_rww_enable();
}

void boot_program_page(uint32_t page){
    
    uint16_t w;
    uint8_t i;
    
    eeprom_busy_wait();
    
    boot_page_erase(page);
    boot_spm_busy_wait();
    
    for (i=0; i<32; i+=2){
        w = (gBuffer[i]) + ((gBuffer[i+1]) << 8);
        boot_page_fill(page+i, w);
    }
    
    boot_page_write(page);
    boot_spm_busy_wait();
    
}

void boot(void){
    
    uint16_t i = 0;//, x = 0, size = 0, type = 0, CS = 0, byte = 0;
    uint32_t /*e_addr = 32000, */addr = 0;
    //uint16_t line[43];
    
    //eraseFlash();
    
    /*
    do {
        
        line[0] = 0;
        
        for(i=0; i<40; i++){
            asm("sei");
            byte = eeGetc(e_addr++);
            RS_putc(byte);
            asm("cli");
            line[i] = byte;
        }
        
        size = get_hex(line[1]);
        size = (size<<8)|get_hex(line[2]);
        
        addr = get_hex(line[3]);
        addr = (addr<<8)|get_hex(line[4]);
        addr = (addr<<8)|get_hex(line[5]);
        addr = (addr<<8)|get_hex(line[6]);
        
        type = get_hex(line[7]);
        type = (type<<8)|get_hex(line[8]);
        
        if(type!=0x00){
            break;
        }
        
        for(i = 0, x = 9; i < 32; i++, x++){
            gBuffer[i] = get_hex(line[x]);
        }
        
        CS = get_hex(line[41]);
        CS = (CS<<8)|get_hex(line[42]);
        
        e_addr++;
        e_addr++;
        
        PORTC ^= (1<<3);
        
        writeFlashPage(addr, SPM_PAGESIZE);
        addr += SPM_PAGESIZE;
        
    } while(addr < 0x0E00);
    */
    
    uint8_t buff[32] = "19C020C01FC01EC01DC01CC01BC01AC0";
    
    for(i=0; i<(sizeof(buff)); i++){
        uint8_t s = buff[i];
        gBuffer[i] = get_hex(s);
    }
    
    boot_program_page(addr);
    
    boot_spm_busy_wait();
    boot_rww_enable();
    
}

int main(void)
{
    
    DDRB = 0xFF;
    DDRC = 0xFF;
    
    eeInit();
    
    //if(get_boarch()){
        asm("cli");
        boot();
    //}
    
    //_delay_ms(3000);
    
    //asm("rjmp 0x0000");
    
    while(1)
    {
        
        do{
            PORTC ^= (1<<3);
            _delay_ms(500);
        }while(1);
        
        
    }
}


уже пробую хотябы просто строку записать не выходит sad.gif

Сообщение отредактировал jackkum - Sep 20 2011, 07:25
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 20 2011, 07:57
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (jackkum @ Sep 20 2011, 10:23) *
Помогите пожалуйста, устал уже 2 дня бродить по инету ничего не могу найти sad.gif
Читайте внимательно ветку, в которую написали. Буквально пару сообщений до вашего:
QUOTE (SysRq @ May 17 2011, 14:10) *
0x1F80 - это в словах (WORD, 2 байта). Здесь указать необходимо в байтах, т.е. на два умножить.


QUOTE (jackkum @ Sep 20 2011, 10:23) *
для меги88 хекс генериться нормально, начинается с адреса 0x0E00

В вашем случае "0xE00 - это в словах (WORD, 2 байта). Здесь указать необходимо в байтах, т.е. на два умножить.". А запускается нормально потому что приложения нет и процессор исполняя код 0xFFFF добегает до начала вашего кода.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


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

 


RSS Текстовая версия Сейчас: 31st July 2025 - 19:42
Рейтинг@Mail.ru


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