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

    

Д_М

Участник
  • Публикаций

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

  • Посещение

Репутация

0 Обычный

Информация о Д_М

  • Звание
    Частый гость

Информация

  • Город
    Краснодар

Посетители профиля

1 717 просмотров профиля
  1. Спасибо большое!
  2. Только заметил, что если требуется 8 бит размер данных UART, то должны быть установлены соответствующие биты в регистрах UART. Если значения будут нулевыми, то размерность получится не 8, а 5 бит. Никогда не заморачивался по этому вопросу и всегда получалось 8 бит. Ни уж то StartUp устанавливает нужные биты, чтобы получился размер 8 бит данных?
  3. Настройка стека данных CSTACK

    Приветствую! Конечная цель - разместить код в загрузчике. Имеется загрузчик AVR230 http://microsin.net/programming/AVR/avr230...bootloader.html Проект имеет уйму настроек. Если что-то неудачно зацепить, концов не найти. Проект был изначально для IAR 2.28. Вроде бы получилось его адаптировать на IAR 6.40. Загрузчик работает, программы тоже. Проблема началась, когда к проекту загрузчика прицепил ранее отлаженный код. Линкер выдаёт следующее: Error[e16]: Segment CSTACK (size: 0xfc0 align: 0) is too long for segment definition. At least 0x2 more bytes needed. The problem occurred while processing the segment placement command "-Z(DATA)CSTACK+(RAM_SIZE-40)=RAM_BASE-(RAM_BASE+RAM_SIZE-1)", where at the moment of placement the available memory ranges were "DATA:142-10ff" Reserved ranges relevant to this placement: DATA:100-101 NEAR_Z DATA:102-141 RSTACK DATA:142-10ff CSTACK Error while running Linker В проекте есть файл .xcl, содержащий следующую строку: -Z(DATA)CSTACK+(RAM_SIZE-40-APP_SRAM_USAGE)=RAM_BASE-(RAM_BASE+RAM_SIZE-1) Несколько мудрёное уравнение. И самое главное, в нём есть неизвестное APP_SRAM_USAGE. Было замечено, что ошибка линкера появляется, когда в обработчике прерывания встречается обращение к структуре через указатель. Когда в теле обычной функции, то всё нормально. И чего линкер прицепился к обработчику прерывания?! #pragma vector=TIMER0_OVF_vect __interrupt void T0_mng (void) { char from_T0; from_T0 = TCNT0; while(from_T0 == TCNT0); TCNT0 += (255-T0_preload); //Syst->swe_Time = Syst->qty_SWI_executors++; /* Вызывает ошибку Линкера */ } В свойствах проекта нет возможности изменить размеры стеков. Получается, что всё определяется файлом .xcl Кто-то знает, как настроить стек данных? Заранее благодарен!
  4. Большое спасибо за помощь!
  5. Когда делаю вот так Syst->SIO1.CRC = CRC(*Syst->SIO1.ptr, Syst->SIO1.CRC, SIO1_poly); Компилятор выдаёт следующее предупреждение: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement D:\Work\MC\Gateway\Actual\Modbus_master1.c 170 И ещё выдаёт такое же предупреждение, когда делаю так if(Syst->SIO1.size < Syst->SIO1.amount) { } Не любит компилятор, когда в одной команде дважды фигурирует обращение к структуре, через указатель. Кажется распутал. Причина оказалась в том, что указатель размещается в строго определённом физическом адресе. __no_init volatile syspar *Syst @0x0100; Так нужно для совместного обращения из applycation и boot секторов. Если сделать просто syspar *Syst; То никакой ругани нет.
  6. extern unsigned int CRC(char data, unsigned int crc, unsigned int poly); void MB1_Send(void) { union { char *ch; int *ui; }target; unsigned char amount = Syst->SIO1.amount, data = *Syst->SIO1.ptr; if(Syst->SIO1.size < amount) { Syst->SIO1.CRC = CRC(*Syst->SIO1.ptr, Syst->SIO1.CRC, SIO1_poly); // Ругается компилятор Syst->SIO1.CRC = CRC(data, Syst->SIO1.CRC, SIO1_poly); // Не ругается компилятор Тоже самое, но через промежуточную локальную переменную.
  7. Объявления unsigned int *crc; syspar Sys; // Декларация структуры типа syspar __no_init volatile syspar *Syst @0x0100; Syst = &Sys; crc = &Syst->SIO1.CRC; // Ругается компилятор crc = &Sys.SIO1.CRC; Error[Pe513]: a value of type "unsigned int volatile *" cannot be assigned to an entity of type "unsigned int *"
  8. Приветствую! Имеется структура и переменная - указатель, которая хранит адрес этой структуры. Обращение к полям структуры через указатель Syst->SIO1.CRC; Проверено, работает. Ничего удивительного. Решил в указатель загрузить адрес поля этой структуры crc = &Syst->SIO1.CRC; Компилятор ругается. Собственно, почему? Технически такое корректно. Меня в своё время очень удивило, что в качестве аргумента можно передавать адреса локальных переменных. Здесь ещё менее хитро, а компилятор ругается.
  9. Разъясните, пожалуйста, про Repeated Start. Правильно ли я понял, что если нужно передавать только отдельные пакеты, то транзакция должна завершаться Stop. В документации сказано, что передача Stop не вызывает прерывания. Если же нужно постоянно передавать что-то без пауз между транзакциями, то транзакция должна завершаться не Stop, а Repeated Start, который будет сразу же началом следующей транзакции. Если же транзакция завершилась командой Stop и сразу же начать новую транзакцию командой Start, произойдёт сбой, так как команда Stop не успеет отработать. Потому у меня и не работало, пока не вставил паузы между Stop и Start. Я прав?
  10. CAN на AT90CAN128

    Всем большое спасибо за помощь! Контроллер довели. CAN работает на 250 kBit/sec. Полноценная, трёхходовая гальваническая изоляция CAN и остальных интерфейсов. Если вдруг, кому-то потребуется завершённый контроллер в промышленном исполнении, на базе AVR, обращайтесь.
  11. Приветствую! Реализовал связь двух AVR по TWI master-slave. Циклическая запись и чтение. Если после завершения записи сразу же начать считывание, и наоборот, но всё зависает. Если же сделать паузы в 2мс, то работает нормально. Так и должно быть, или имеет место косяк в программе?
  12. CAN на AT90CAN128

    Разобрались! Проблема, как и думалось, была аппаратная. Софт рабочий. Проверен на отладочной плате от Olimex. С реальным датчиком работает.
  13. Программы систем реального времени, по моему мнению, следует строить по принципу - на каждое событие есть свой обработчик. Завершилось преобразование АЦП, сработало прерывание, нужно сохранить данные и вызывать обработчик фоновой задачи, который преобразует сырые данные АЦП в формат с плавающей точкой. После завершения математики можно разрешать новое преобразование. Запускать новое преобразование АЦП, до того, как процессор завершит обработку, смысла нет. Чтобы программа так работала нужен диспетчер многозадачности. Вытесняющая многозадачность для одной единственной программы, которую пишешь сам - перебор. Кооперативной вполне достаточно. Есть два заблуждения. Заблуждение первое - кооперативная многозадачность создаёт множество неудобств. Заблуждение второе - вытесняющая многозадачность эти удобства решает. По степени важности обработчики делятся на три уровня - аппаратные прерывания (срочно, срочнее некуда), программные прерывания (не так срочно, как аппаратное прерывание, но срочнее, чем фоновая задача), фоновая задача (по остаточному принципу - сложная математика). Обработчик аппаратного прерывания инициирует либо программное прерывание, либо фоновую задачу. Системный таймер - надстройка над механизмом программного прерывания.
  14. Приветствую! Это нужно для того, чтобы векторы прерываний, расположенные в загрузочном секторе, передавали управление функциям, расположенном в секторе приложений. Адрес может быть произвольным, но одинаковым, как для загрузчика, так и для приложения. Делал вот так __no_init volatile unsigned int Sys_ptr @0x0100; Компилятор IAR ошибок не выдает. Работает. Смущает, что в начале работы программы в этой ячейке не нулевое значение. Правильно ли я делал? Можно ли быть уверенным, что при такой декларации переменной не будет пересечения со стеками и данными? Хотел, для уверенности, разместить эту переменную в области I/O (0x00..0xFF), на какой-то зарезервированный адрес, в частности 0x76. Не тут то было! Значение постоянно плавает. Если адрес зарезервирован, то это не значит, что его можно использовать, как ячейку памяти. Спасибо!
  15. Вызов функций из bootloader

    А как будет выглядеть вызов функции с параметрами? void MyFunc(unsigned int MyPar) { }