Я надеюсь, что это четкое объяснение моей проблемы. Я чуть более недели бегал по разным учебникам, сейчас пытаюсь решить эту проблему:
Недавно я занимался редизайном дизайна программного обеспечения для класса.проект после обратной связи и тестирования на STM32 Nucleo-F334R8 (мой исходный код был пронизан ошибками памяти и синхронизации)
При обработке данных USART с использованиемUSART 1 в асинхронном режиме со скоростью 115200 бод:
Запрограммируйте полученный сигнал SIGTRAP, Trap / breakpoint trap.0x08002c08 в memset ()
Запрограммировать полученный сигнал SIGTRAP, Trap / breakpoint trap.0x08002c08 в memset ()
Запрограммировать полученный сигнал SIGTRAP, Trap / breakpoint trap.0x08002c08 в memset ()
Запрограммировать полученный сигнал SIGTRAP, Trap / breakpoint trap.0x08002c08 в memset ()
Запрограммировать полученный сигнал SIGTRAP, Trap / breakpoint trap.0x080056b4 в std.isra ()
Значение, хранящееся по адресу 0x08002c08, о котором идет речь, обычно очень большое, обычно что-то вроде 134228385 в десятичном виде.Также, если я решительно пошагово рассмотрю проблему, программа продолжит нормально работать, и никогда не встретится с проблемой снова , что я нахожу странной возможной причиной?
ОБНОВЛЕНИЕ: Итак, я проследил проблему memset вокругнемного и обнаружил, что это происходит во время моего setOutputBuffer
метода:
String>,%5d,%8s,%3d,%3d,%3d,%4d,%4d,%4d,%10.6f,%11.6f,%7.1f,%3d,%3.1f\n",uptime,timeString,temperature,pressure,humidity,acc1,acc2,acc3,latitude,longitude,altitude,current,voltage);
} ``` Which leads me to believe the issue lies in finding a value that
is being used to set the Output buffer message.
I would like advice on how to further troubleshoot these two issues
and whether there is a chance that the memset error is related the
later bss error.
My String Tokenizing code(edited):
```c void tokenize(char* in){ const char *p = in; const char
delim[] = ","; char *token = NULL; uint8_t n = 0;
do{
size_t length = strcspn(p, delim); if(length > 0){ if(token ==
NULL){
token = malloc(sizeof(char)*length); // create memory space for the token
memset(token, 0, length); // ensure initialized memory is blank
sprintf(token, "%.*s",(int)length,p); // store the token from a substring of Input Buffer
p+=length; // move pointer to next ','
parseToken(token, n); // extract information from the token be it latitude, longitude etc
memset(token, 0, length); // clear the token
free(token); // free up the token's spot in memory
token = NULL; // set token pointer to null
n++; }
}
}while(*((++p)+1) != '*'); // The expected string ends with a
checksum character '*' after the last ',' } ``` I've re-examined the
function and made a lot of changes now I can successfully step through
the entire function without issue, the program then returns to my main
loop, and I let it run for a while but then I suddenly run back into
the same memset issue, even without receiving any bytes over USART
here is the code for my main loop and the subsequent function calls it
makes:
```c
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if (byteFlag){ byteRecieved(); byteFlag = 0; }
if(msgFlag){ msgRecieved(); msgFlag = 0; }
if(secFlag){ setOutputBuffer(); HAL_UART_Transmit(&huart1,
(uint8_t *)bufferOut, 91, 1000); secFlag = 0; }
} ``` byteReceived: ```c if((char) byteIn == '$'){
clearInputBuffer(); } else if((char) byteIn == '\n'){
msgFlag = 1; }
else{ storeChar(); } ```
msgReceived: ```c if(isValid()){ if (checksum()) {
tokenize(bufferIn); clearInputBuffer(); } } ```
isValid: ```c char substr[5]; strncpy(substr, (bufferIn+1), 5);
if(!strcmp(substr, "GPGGA")){ return 1; }
return 0; ```
checksum: ```c int checksum(){ int calc_checksum = 0; int
in_checksum; int i = 0; char checkstr[2]; uint8_t hasCheckSum = 0;
for(int j = 0; j<91; j++){ if (bufferIn[j] == '*') { hasCheckSum
= 1; i = 1; } }
if (hasCheckSum) { while (bufferIn[i] != '*'){ calc_checksum ^=
bufferIn[i]; i++; } checkstr[0] = bufferIn[i+1]; checkstr[1]
= bufferIn[i+2]; } else {return 0;}
in_checksum = parseStr_HexToInt(checkstr);
if (calc_checksum == in_checksum){ return 1; } else { return 0;
} } ```
clearInputBuffer: ```c void clearInputBuffer(){ int i = 0;
for(i = 0; i < 100; i++){ bufferIn[i] = ' '; } bufferIn[0] = '$';
} ```
Я обнаружил ловушку точки останова при заполнении сегмента bss памяти платы
И после добавления семи портов GPIO дляЖК-дисплей в 4-битном режиме (а именно PA12, PA11, PB12, PB11, PB2, PB1, PB15) и два для двухканального АЦП в режиме DMA (PA1, PA0):
Запрограммируйте принятый сигнал SIGTRAP,Трассировка / Точка останова.LoopFillZerobss () at .. \ startup / startup_stm32f334x8.s: 103 103 cmp r2, r3 При попытке реализовать функции LCD и ADC я получаю сообщение об ошибке прерывания точки останова во время запуска функции LoopFillZerobss, которая оказалась фатальной , особенноотключив мой USART от отчетов вообще (однако он все еще может получать байты в качестве прерываний и обрабатывать токены и т. д., просто отказывается передавать), прочитав сегмент bss, я попытался решить проблему, инициализировав какМногие глобальные переменные, как я мог бы к ненулевым значениям, это не сработало, проблема наблюдается после добавления настроек STM32CubeMx для АЦП и 7 выводов GPIO, используемых на ЖК-дисплее, однако ни одна из них не использует, насколько мне известно, унифицированные переменные, если толькопредопределенный код, сгенерированный CubeMX, выходит за пределы сегмента памяти bss и что размер сегмента bss слишком велик для памяти платы (что, я подозреваю, маловероятно, но не исключает).
ЭссенИдея этого проекта заключается в том, чтобы получать различные данные через USART, ADC и более поздние I2C и отображать различные аспекты данных через USART и LCD в настоящее время, если я отбрасываю ошибки ADC и LCD, мой код USART функционирует, так как ошибка memset ()не смертельно, но я подозреваю, что выход из него вызывает у меня только более поздние проблемы, но я также не уверен, где исправить мой код токенизации, предполагая, что это корень моих проблем.