Цитата(ШСА @ Nov 4 2015, 11:30)

Я тоже, но только если HAL годится не только для Keil. Я CooCos-ник.
Я перенес с Кейла на Кокос. Единственное что было неочевидно сходу -- использование другого имени переменной начала стэка в линкер файле. Пришлось минут 15 поискать.
В стартап файле:
Drivers\CMSIS\Device\ST\STM32F4xx\Source\Templates\gcc\startup_stm32f429xx.s
ldr sp, =_estack /* set stack pointer */
.word _estack
Заменить на
ldr sp, =_eram /* set stack pointer */
.word _eram
Иначе линкер ругается на то, что _estack неопределен.
По поводу темы. Полностью поддерживаю топик стартера. Я тоже достаточно опытный программист микроконтроллеров и не вижу больших проблем с автогенератором. Ну надо изучать структуру полученного кода. Так то что она есть это скорее достоинство. Г-код это когда бессистемное нагромождение кода без продуманных идей. А проблемы со скоростью критических прерываний если потребуется я решу. Да и то если понадобится. Какие основные проблемы с автогенерацией возможны?
1. Баги. А кто без греха?
2. Размер кода. Пока помещается никто с этим не заморачивается. Система интеграции мобильника в БМВ занимает 130 килобайт кода:
http://www.ebay.co.uk/itm/NEW-GENUINE-BMW-...0-/291387105166Прикиньте насколько можно поджимать код, когда прижмет.
Кстати мой любимый Source Insight тоже не такой много места занимает.
3. Быстродействие. Пока не поджимает никому не важно, а начнутся проблемы -- легко решить.
Цитата(esaulenka @ Nov 4 2015, 13:03)

Нафиг-нафиг это HAL.
В случае "что-то пошло не так" разобраться в этом наслоении абстракций довольно сложно.
Судя по слухам "в HAL используется Keil RTOS", "HAL поддерживается только в Keil" и т.д., это не только моя проблема :-)
Библиотеки уровня "подрыгать ножкой" и "включить ШИМ" пишутся под конкретные требования на коленке за полчаса.
Заодно и виновный во всех косяках доступен :-)
PS что присутствующие подразумевают под CMSIS, я не понял. Есть CMSIS core - набор функций/макросов для доступа к ядру и его периферии (NVIC, например). Это есть, и это удобно.
А идея "все производители чипов напишут единообразный CMSIS Driver API" не взлетела. Я, во всяком случае, не видел.
http://www.arm.com/products/processors/cor...ce-standard.phpДа ладно вам. Вы не видели кода для фрискейловского АРМа с зигби периферией. Не помню навскидку его имени. Там один хедер файл и из него ифдефами разные части программы получают разные его варианты. Натуральный шифрокод. Я даже и времени не стал тратить -- нашел обходной маневр.
Цитата(Ruslan1 @ Nov 4 2015, 20:49)

Ну что же, немного прояснил кое-что для себя
1. Не могу работать в структуре Куба. хочу структуру файлов, которую раньше использовал и привык
Мне редко удавалось использовать то, что я привык. Даже не заморачиваюсь с этим.
Цитата(Ruslan1 @ Nov 4 2015, 20:49)

2. Посмотрел USART. мда, как-то они намутили с проверками и коллбеками, через эту цепь вызовов даже в прерывании продираться нужно, причем вызовы с аргументами. А у меня есть интерфейсы, где таймауты жестко заданы (например, sdi-12, или modbus-rtu ), или прерывания от внешних сигналов. И даже если я засуну свой код в предусмотренное для этого место в исходнике, то вызов HAL_UART_IRQHandler() никуда не денется. А если его удалить, то при следующей генерации кода он опять
Мне UART нужен для дебага только. Я только передатчик использую. Если использовать DMA, то вызывается на все строку только прерывание конец DMA. Да и передача красиво происходит. Вызвал функцию передачи и забыл. Оне не блокирующая. Реалтайм не страдает.
На прием сообщений произвольной длины DMA использовать красиво не получится если надо их в реаьном времени обрабатывать. Но кто мешает переписать обработчик прерывания?
Цитата(rudy_b @ Nov 6 2015, 01:33)

Вот именно про это я и писал - HAL по DMA запускает передачу последнего байта, а, затем, по прямому поллингу TC дожидается завершения передачи последнего байта - и это в функции обработки прерывания DMA.
На скорости 115 кбод это приводит к завешиванию равных и более низкопроиоритетных прерываний (ну и всего нижележащего) примерно на 12 мксек (длительность передачи одного байта). Соответственно завешивается приемник (если он на равном или низшем приоритете) и получаем ORE.
Это легко убирается либо коррекцией кода HAL, либо снижением приоритета прерываний DMA передачи ниже DMA приема (именно priority, а не subpriority).
Что-то не вижу ожиданий в коде. Можете поподробнее рассказать пожалуйста?
CODE
/**
* @brief Handles DMA interrupt request.
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval None
*/
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
/* Transfer Error Interrupt management ***************************************/
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
{
/* Disable the transfer error interrupt */
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
/* Clear the transfer error flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_TE;
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if(hdma->XferErrorCallback != NULL)
{
/* Transfer error callback */
hdma->XferErrorCallback(hdma);
}
}
}
/* FIFO Error Interrupt management ******************************************/
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma)) != RESET)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
{
/* Disable the FIFO Error interrupt */
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_FE);
/* Clear the FIFO error flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_FE_FLAG_INDEX(hdma));
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_FE;
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if(hdma->XferErrorCallback != NULL)
{
/* Transfer error callback */
hdma->XferErrorCallback(hdma);
}
}
}
/* Direct Mode Error Interrupt management ***********************************/
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma)) != RESET)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != RESET)
{
/* Disable the direct mode Error interrupt */
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_DME);
/* Clear the direct mode error flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_DME_FLAG_INDEX(hdma));
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_DME;
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if(hdma->XferErrorCallback != NULL)
{
/* Transfer error callback */
hdma->XferErrorCallback(hdma);
}
}
}
/* Half Transfer Complete Interrupt management ******************************/
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
{
/* Multi_Buffering mode enabled */
if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
{
/* Clear the half transfer complete flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
/* Current memory buffer used is Memory 0 */
if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
{
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
}
/* Current memory buffer used is Memory 1 */
else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
{
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_READY_HALF_MEM1;
}
}
else
{
/* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
{
/* Disable the half transfer interrupt */
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
}
/* Clear the half transfer complete flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
/* Change DMA peripheral state */
hdma->State = HAL_DMA_STATE_READY_HALF_MEM0;
}
if(hdma->XferHalfCpltCallback != NULL)
{
/* Half transfer callback */
hdma->XferHalfCpltCallback(hdma);
}
}
}
/* Transfer Complete Interrupt management ***********************************/
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
{
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
{
if(((hdma->Instance->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0)
{
/* Clear the transfer complete flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
/* Current memory buffer used is Memory 1 */
if((hdma->Instance->CR & DMA_SxCR_CT) == 0)
{
if(hdma->XferM1CpltCallback != NULL)
{
/* Transfer complete Callback for memory1 */
hdma->XferM1CpltCallback(hdma);
}
}
/* Current memory buffer used is Memory 0 */
else if((hdma->Instance->CR & DMA_SxCR_CT) != 0)
{
if(hdma->XferCpltCallback != NULL)
{
/* Transfer complete Callback for memory0 */
hdma->XferCpltCallback(hdma);
}
}
}
/* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
else
{
if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0)
{
/* Disable the transfer complete interrupt */
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
}
/* Clear the transfer complete flag */
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
/* Update error code */
hdma->ErrorCode |= HAL_DMA_ERROR_NONE;
/* Change the DMA state */
hdma->State = HAL_DMA_STATE_READY_MEM0;
/* Process Unlocked */
__HAL_UNLOCK(hdma);
if(hdma->XferCpltCallback != NULL)
{
/* Transfer complete callback */
hdma->XferCpltCallback(hdma);
}
}
}
}
}