Перейти к содержанию
    

KSN

Свой
  • Постов

    406
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные KSN


  1. Доброго дня. Использую такой подход:

    // configData размещается во flash памяти.

    #pragma section "FLASH"

    #pragma location = "FLASH"

    __root const SettingStruct configData = { /*начальные значения элементов структуры SettingStruct*/};

    // Объявляю указатель на структуру. Указатель размещается в RAM.

    SettingStruct *toConfig;

    void main()

    {

    // Инициализация указателя.

    toConfig = (SettingStruct*)&configData;

    ....

    }

    Доступ к значению во flash: toConfig->...

    Изменение значений: через процедуру перезаписи страницы flash памяти.

  2. Коллеги, подскажите, где можно изготовить нагревательный элемент открытого типа с двумя контурами 1700 и 1200 Вт, каркас - слюда, нихром, 600-800 градусов, формовка проволки - змейка. Напряжение сетевое ~220 В

  3. При изготовлении прототипа платы количество слоев скажется на стоимости. При серийном производстве: стоимость в зависимости от количества слоев уже не сильно заметна.

  4. Скажем, питание было выдернуто (передернуто) в процессе обмена данными через эту область ОЗУ и тем более в процессе заливки новой прошивки.

    Есть защита от подобных сбоев?

    Да, конечно. Проверка CRC прошивки, область bootloaderа защищена. При возникновение такой ситуации устройство перезагрузится, останется в bootloader, при этом по интерфейсу будет послано сообщение в систему.

  5. По поводу непрерывного протокола обмена.

    Делаю так: в RAM есть структура, которая не инициализируется средствами компилятора при старте программы. Через эту структуру bootloader и application обмениваются информацией( вызов bootloadera из application, возврат из bootloader в application). Использую какие-нибудь хитрые значения для этих переменных, а не простые 0x00000000, 0xFFFFFFFF, наподобие значение переменных для снятие блокировки с watch-dog, flash memory в stm32f.

    Работает так: прилетает команда по интерфейсу "перейти в bootloder". Application отвечает, что команда принята, выполняет необходимы действия, устанавливает переменную и вызов bootloader. Bootloader "понимает" что был переход по команде, шлет по интерфейсу подтверждение исполнения команды и далее обрабатываются команды для bootloadera. После завершения обновления прошивки, приходит команда "выйти из bootloader" - посылается ответ, что команда принята, устанавливается переменная, выполняются необходимые действия и переход в Application. Application "понимает", что был выход из bootloadera по команде, шлет "подтверждение исполнения" команды и продолжает исполняться код приложения.

  6. Парсить ваш код времени нет, сорри.

    Вот рабочий пример:

    
    void OV7670_Snapshot2RAMBuffer(void)
    {
     DMA_InitTypeDef  DMA_InitStructure;
     NVIC_InitTypeDef NVIC_InitStructure;
    
       // Включение тактирования
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    
     // DMA деинициализация
     DMA_Cmd(DMA2_Stream1, DISABLE);
     DMA_DeInit(DMA2_Stream1);
     DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);  
    
       /* Enable the DMA Stream IRQ Channel */
     NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);     
       /* Enable the DMA Stream IRQ Channel */
     NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);     
     dma2Stream0 = 0;
     dma2Stream1 = 0;
    
     DMA_DoubleBufferModeConfig(DMA2_Stream1,(uint32_t)&ov7670_ram1[0],DMA_Memory_0);
     DMA_DoubleBufferModeCmd(DMA2_Stream1, ENABLE);
    
     // DMA инициализация
     DMA_InitStructure.DMA_Channel = DMA_Channel_1;
     DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS;
     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ov7670_ram0;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
     DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE_WORD;
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     DMA_Init(DMA2_Stream1, &DMA_InitStructure);
    
     DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);  
    
     /* Enable DMA Stream Transfer Complete interrupt */
     DMA_ITConfig(DMA2_Stream1, DMA_IT_TC, ENABLE);
    
     // DMA деинициализация
     DMA_Cmd(DMA2_Stream0, DISABLE);
     DMA_DeInit(DMA2_Stream0);
     DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);  
    
       // DMA инициализация
         DMA_InitStructure.DMA_Channel = DMA_Channel_0;
         DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ov7670_ram0[0];
         DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(SDRAM_BANK_ADDR);
         DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory;
         DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE_WORD;
         DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
         DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
         DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
         DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
         DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
         DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
         DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
         DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
         DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4;
         DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4;
         DMA_Init(DMA2_Stream0, &DMA_InitStructure);
    
         DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);  
         /* Enable DMA Stream Transfer Complete interrupt */
         DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
    
     // DMA включен
     DMA_Cmd(DMA2_Stream1, ENABLE);
     // DCMI инициализация
     OV7670_InitDCMI(1);
     // DCMI включен
     DCMI_Cmd(ENABLE);
     // Capture включен
     DCMI_CaptureCmd(ENABLE);
    }
    
    void DMA2_Stream1_IRQHandler(void)
    {
     /* Test on DMA Stream Transfer Complete interrupt */
     if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1))
     {
       /* Clear DMA Stream Transfer Complete interrupt pending bit */
       DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1);
       if (DMA2_Stream1->CR&0x00080000) { /* ram1*/
         DMA2_Stream0->PAR = (uint32_t)&ov7670_ram0[0];
         DMA2_Stream0->M0AR = (uint32_t)(SDRAM_BANK_ADDR + dma2Stream1*76800);
       } else {  /* ram0 */
         DMA2_Stream0->PAR = (uint32_t)&ov7670_ram1[0];
         DMA2_Stream0->M0AR = (uint32_t)(SDRAM_BANK_ADDR + dma2Stream1*76800);
       }
       DMA2_Stream0->CR |= (uint32_t)DMA_SxCR_EN;
       dma2Stream1++;
     }
    }
    
    //#warning "Uncomment function for DCMI used"
    void DMA2_Stream0_IRQHandler(void)
    {
     /* Test on DMA Stream Transfer Complete interrupt */
     if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
     {
       /* Clear DMA Stream Transfer Complete interrupt pending bit */
       DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
       dma2Stream0++;
     }
    }
    

    Принцип следующий:

    есть 2 буфера в RAM по 19200 32-х разрядных слов. Один канал DMA берет данные с камеры и кидает в активный буфер (по кольцу). Второй канал DMA из RAM перекидывает в SRAM(внешняя), т.к. для разрешения 640x480 необходимо 307200*2=614400 байт(формат YUV). Clock камеры 24Мгц

  7. to khach, знать количество устройств очень полезно, но есть некоторые замечания:

    1. Как только в руки заказчика попадает открытый загрузчик, то ничто ему не мешает дизассемблировать его.

    2. Если шифруем прошивку открытым ключом, то пп1 и получаем доступную прошивку.

    3. Сгенерировать новый ключ не так просто. Старшие семейства MCU имеют аппаратный RNG, младшие - нет, прийдется изголяться.

  8. Можно через ж..у сделать конечно, например используя серийник чипа, как ключ. Но тогда нужно заказчика просить считать эти номера с камней и прислать вам.

    Прислали мне серийник камня. И...?

  9. Сорри, упустил из виду, что тут такие дебаты.

    По MCU: использую stm32f103R(V)BT6, STM32F205RB(V)T6, STM32F429(буквы не помню). Стандартно под загрузчик отдаю первые 1-3- страницы по 1кБайту или 1 по 16кБайт. Загрузчик залочен. Обновление прошивки производится по CAN. Мысль бродит, как так сделать, чтобы заказчик сам прошивал свои МК с помощью встроенного бутлодера, но чтобы самая первая передаваемая ему прошивка была зашифрована и не могла ни дешифроваться, ни зашита в МК с помощью программатора и т.д.(чтобы кристаллы не возить туда-обратно, заказчик сам купил кристаллы и сам прошил) Но видимо, без первого программирования залоченого бутлодера с помощью программатора никак.

  10. Существует ли возможность с помощью встроенного бутлодера загружать шифрованную прошивку, так чтобы нельзя было ее дешифровать? В настоящее время использую собственный загрузчик, но с ростом семейства STM32F увеличивается мин. объем сектора. Объем кода загрузчика <3кБайт и отдавать ему 16кБайт - жалко.

  11. Ну можете линкером его куда угодно залинковать.

    Возникла необходимость вычислить две контрольные суммы. Для __checksum считается без проблем, а вот посчитать другую область и разместить по абсолютному адресу - не получается. Проект был создан во времена 5.3, поэтому и решил в его инструментарии покопаться.

    С помощью S-Record получил, что хотел. Попробуем версии 7.x

  12. Читать документацию. Есть всякие псевдо типа ROMSTART, RAMSTART и само-собой __segment_beginn() и иже с ним

    Ясно, буду копать. Тут еще обнаружилось, что ielftool (в данной версии), размещает контр. сумму только по имени символу __checksum, по абсолютному адресу - ни в какую.

  13. Как сделать это вручную, без привлечения IDE IAR ARM? Т.е. как и чем узнать размер области кода и сколько осталось незадействованной. Хотелось бы как-то автоматизировать этот процесс, чтобы потом скормить ielftool.

×
×
  • Создать...