Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Почему не работает чтение из буфера 2?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Димон Безпарольный
Написал код подстановки в функцию чтения из последовательного порта:

Код
int spwf_socket_read (unsigned char* i, int ch, int timeout)
{                                                //
    unsigned char *PacketPntr = NULL;            //
    static int PacketIDX = 0;                    //
    int dataLen = 0;                            //
    
    //printf("\nPacketType = %d:", PacketSwitch);//
    
    printf("\nAsking NByte = %d:", ch);            //

    if(PacketSwitch == 2)                        //
        {                                        //
            PacketPntr = CONNACK_P;                //
            printf("IDX = %d:", PacketPntr);    //
        }                                        //
        
    if(PacketSwitch == 9)                        //
        {                                        //
            PacketPntr = SUBACK_P;                //
            printf("IDX = %d:", PacketPntr);    //
        }                                        //
    while(1)                                    //
        {                                        //
            i[dataLen] = PacketPntr[PacketIDX++];//Кладем в буфер
            printf("%02x ", i[dataLen]);        //
            dataLen++;                            //
            if(dataLen >= ch) {break;}            //Если принято сколько сказано (int ch) - выход        
        }                                        //
    return dataLen;                                //
}                                                //

В первом случае (PacketSwitch == 2), код работает исправно. Во втором случае читаются нули:

Цитата
Connect to MQTT Brocker

Asking NByte = 1:IDX = 4235388:20
Asking NByte = 1:IDX = 4235388:02
Asking NByte = 2:IDX = 4235388:00 00
Connected with IBM MQTT broker
Subscribing topic: iot-2/cmd/rele/fmt/json
Asking NByte = 1:IDX = 4235392:00
Asking NByte = 1:IDX = 4235392:00
MQTTSubscribe. Timeout expired for suback reception


Массивы объявлены глобально. Можно и локально, будет то же самое.

Цитата
unsigned char CONNACK_P[4] = {0x20,0x02,0,0}; //
unsigned char SUBACK_P [4] = {0x90,0x03,0,0}; //
SSerge
Цитата
static int PacketIDX = 0;

Зачем там static?
Димон Безпарольный
Цитата(SSerge @ Aug 7 2017, 17:08) *
Зачем там static?

Согласен не нужен. Но без него еще хуже:

Цитата
Connect to MQTT Brocker

Asking NByte = 1:IDX = 4235388:20
Asking NByte = 1:IDX = 4235388:20
Asking NByte = 32:IDX = 4235388:20 02 00 00 90 03 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Client connection with IBM MQTT broker failed with Error Code 2
Connection Refused, identifier rejected

MQTT Error.. Try again... 0
Для продолжения нажмите любую клавишу . . .


Глупость, понимаю. Но не могу понять где накосячил.
adnega
Цитата(Димон Безпарольный @ Aug 7 2017, 17:17) *
Глупость, понимаю. Но не могу понять где накосячил.

А кто и когда обнуляет PacketIDX ?
SSerge
Что эта функция вообще должна делать?
x893
static не нужен конечно
Второй случай смотрите отладчиком.
Кто то у вас затирает SUBACK_P нулями.

Димон Безпарольный
Цитата(adnega @ Aug 7 2017, 18:35) *
А кто и когда обнуляет PacketIDX ?

Так его вроде и обнулять не надо. При старте static int PacketIDX = 0; а дальше присвоение PacketPntr = CONNACK_P.

x893
Если static добавить, то работать будет неправильно и будет выход за границу.
Возьмите карандаш с бумажкой и промоделируйте работу программы.
Можно книжками заменить про язык С.
dm37
У вас всё работает так как вы и написали. Т.е. если не сбрасывать PacketIDX, то при выборке из второго массива будет считываться не элемент 0, а элемент 4
можно, как вариант сделать так:

Код
    unsigned char *PacketPntr = NULL;            //
    static int PacketIDX = 0;                    //
       static int packet_switch = 0;
    int dataLen = 0;                            //
    
    //printf("\nPacketType = %d:", PacketSwitch);//
    
    printf("\nAsking NByte = %d:", ch);            //

    if(packet_switch != PacketSwitch)
    {
        PacketIDX = 0;
        packet_switch = PacketSwitch;
    }

...
x893
Сделать можно как угодно, но телепатия пока не доступна простым начинающим типа меня.
Как сейчас нарисовано, то конечно могут быть ошибки при выходе за границы.
Димон Безпарольный
Цитата(x893 @ Aug 7 2017, 21:35) *
Если static добавить, то работать будет неправильно и будет выход за границу.
Возьмите карандаш с бумажкой и промоделируйте работу программы.
Можно книжками заменить про язык С.

Именно так. Первый пакет читался правильно, поскольку PacketIDX = 0. Второй - уже не правильно. Но сложность в том, что текущий принятый пакет внешние функции должны читать по частям. Т.е. первое обращение - 1 байт, второе обращение - 2 байта. Вышел из положения добавив:

Код
    if(PacketIDX >=3) {PacketIDX = 0;}


Учитывая что пакет в данном случае пока трехбайтовый. И заработало. Извиняюсь что заморочил людям голову. Об этом мог знать только я. Проблемы с памятью все же есть, но они в других местах. А я подумал что и в этом...
x893
Тогда логику надо изменить.
Kibi
Эм, а не проще ли switch(PacketIDX), просто как то странно из кучи последовательных ифоф, особенно когда байт много и при каждом проходе нужно обращаться к определенному по номеру байту, хотя может неправильно понял задачу.
Димон Безпарольный
Цитата(Kibi @ Aug 8 2017, 17:32) *
Эм, а не проще ли switch(PacketIDX), просто как то странно из кучи последовательных ифоф, особенно когда байт много и при каждом проходе нужно обращаться к определенному по номеру байту, хотя может неправильно понял задачу.

Можно. switch(PacketIDX) или ИФ переключает тип протокола. По нему выбирается строка. И так и так можно. Только протоколов всего 5 будет.
x893
Я бы на этот вопрос
"Почему не работает ... ?"
ответил так
Логику надо улучшать
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.