Sep. 26th, 2024

eddy_em: (Default)
Решил было сэкономить объем text-секции в микроконтроллере и используемые по нескольку раз строковые константы объявить именно как константы. Однако, gcc, зараза такая, не хочет при компиляции в массив, использующий эти строки, подставить именно переменные, несмотря на то, что они - константы. Вот простой пример:
#include <stdio.h>

static const char * text1 = "One";
static const char * text2 = "Two";
static const char * text3 = "Three";

static const char * const array[3] = {text1, text2, text3};

int main(){
	for(int i = 0; i < 3; ++i) printf("%d: %s\n", i, array[i]);
	return 0;
}

Выхлоп:
gcc 2.c 
2.c:7:39: ошибка: элемент инициализатора не является константой
    7 | static const char * const array[3] = {text1, text2, text3};
      |                                       ^~~~~
2.c:7:39: замечание: (где-то рядом с инициализацией для «array[0]»)
2.c:7:46: ошибка: элемент инициализатора не является константой
    7 | static const char * const array[3] = {text1, text2, text3};
      |                                              ^~~~~
2.c:7:46: замечание: (где-то рядом с инициализацией для «array[1]»)
2.c:7:53: ошибка: элемент инициализатора не является константой
    7 | static const char * const array[3] = {text1, text2, text3};
      |                                                     ^~~~~
2.c:7:53: замечание: (где-то рядом с инициализацией для «array[2]»)

Однако, вот так прокатывает:
#include <stdio.h>

static const char * text1 = "One";
static const char * text2 = "Two";
static const char * text3 = "Three";

static const char ** const array[3] = {&text1, &text2, &text3};

int main(){
        for(int i = 0; i < 3; ++i) printf("%d: %s\n", i, *array[i]);
        return 0;
}


Ну, значит, придется делать массив указателей на указатели…
eddy_em: (Default)
Код на вражеском гитхабе.
Позже выложу описание протокола. Пока вкратце, что умеет:
- работа с RS-232 (текстовый протокол), RS-485 (modbus-rtu) и CAN (мой "стандартный" протокол);
- возможность при изменении состояния дискретных входов отправлять по CAN текущее состояние;
- возможность связать несколько устройств так, что одно будет по CAN и/или modbus (но лишь в случае если оно — господин шины) слать команду с нужным идентификатором (или 0 - широковещательную), чтобы в соответствии с изменением входов щелкали релюшки.
В остальном все как и было раньше.
Код еще не совсем закончен, т.к. обнаружилась странная ошибка с CAN (кстати, она есть и на USB-CAN устройствах, но там проявляется лишь на очень больших скоростях): если выводить данные во время приема, то как только выведен заполненный до конца буфер, происходит зависание и watchdog через 2 секунды перезагружает МК. Я уже даже в обработчики прерываний ошибок CAN-шины воткнул отключение CAN — бесполезно! Т.е. нужно подключать отладчик, отключать watchdog и, когда МК перейдет в hardfault_handler, посмотреть в стеке адрес возврата и по нему попытаться определить, на какой последней инструкции возник косяк. Но вот проблема: здесь нога отладчика используется для управления DE преобразователя уровней RS-485. Похоже, придется отключить на время отладки 485 и попытаться таки понять, что за НËХ!

April 2025

S M T W T F S
  1 23 45
67 89101112
13141516171819
20212223242526
27282930   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 22nd, 2025 06:12 am
Powered by Dreamwidth Studios