Допустим у нас есть функция, которая принимает в себя указатель. Мы знаем, что в указателе лежит нуль-терминальная строка, а за ней 4-байтное целое.
Вы подобрали пример, в котором лишили компилятор возможности помочь вам с типами данных и работой с ними. Зачем? Возможно, передача структуры с двумя полями (строка и целое) решит проблему? Всякие стандарты вроде MISRA-C уже после void* валерьянку пьют, а после memcpy да и без проверки на успешность выделения памяти так и рыдать и курить начинают.
Позволю добавить, КМП примечателен отсутствием сдвига указателя чтения «назад», тем самым позволяя просматривать поток данных.
Префикс-функция, о которой велась речь в статье, выстраивает конечный автомат, по которому движется алгоритм при поиске подстроки. Это позволяет переложить такой алгоритм на ASIC/FPGA и сферу применения — intrusion detection systems, где данных много, да еще и хранить их для дальнейшего анализа не всегда возможно.
что-то похожее на атмосферу на снимке — это результат обработки изображения или там действительно есть атмосфера? О_о
Скорее всего, засвет какой-нить, но вдруг это что-то важное :)
спасибо. я рад, что смог донести мысль. Именно реализации на HAL позволяют использовать их в многозадачных решениях и позволяют добиться отказоустойчивости за счет таймаутов в блокируемых вызовах.
Вот собственно реализация функции. Столь высокая сложность обсусловлена соблюдением MISRA C 2004 и совместимости с RTOS. Но вы без труда найдете проверку флагов. Функция передачи с использованием прерываний немного проще, но все так же обвешена проверками для соблюдения MISRA.
HAL_SPI_TransmitReceive
/**
* @brief Transmit and Receive an amount of data in blocking mode.
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @param pTxData: pointer to transmission data buffer
* @param pRxData: pointer to reception data buffer
* @param Size: amount of data to be sent and received
* @param Timeout: Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
{
#ifdef USE_SPI_CRC
__IO uint16_t tmpreg = 0U;
#endif
uint32_t tickstart = 0U;
HAL_StatusTypeDef errorcode = HAL_OK;
/* Check Direction parameter */
assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
/* Process Locked */
__HAL_LOCK(hspi);
/* Init tickstart for timeout managment*/
tickstart = HAL_GetTick();
if(!((hspi->State == HAL_SPI_STATE_READY) || \
((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX))))
{
errorcode = HAL_BUSY;
goto error;
}
if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
/* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
if(hspi->State == HAL_SPI_STATE_READY)
{
hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
}
/* Set the transaction information */
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
hspi->pRxBuffPtr = (uint8_t *)pRxData;
hspi->RxXferCount = Size;
hspi->RxXferSize = Size;
hspi->pTxBuffPtr = (uint8_t *)pTxData;
hspi->TxXferCount = Size;
hspi->TxXferSize = Size;
/*Init field not used in handle to zero */
hspi->RxISR = NULL;
hspi->TxISR = NULL;
#ifdef USE_SPI_CRC
/* Reset CRC Calculation */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
SPI_RESET_CRC(hspi);
}
#endif
/* Check if the SPI is already enabled */
if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
{
/* Enable SPI peripheral */
__HAL_SPI_ENABLE(hspi);
}
/* Transmit and Receive data in 16 Bit mode */
if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
{
while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
{
/* Check TXE flag */
if((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
{
hspi->Instance->DR = *((uint16_t *)pTxData);
pTxData += sizeof(uint16_t);
hspi->TxXferCount--;
#ifdef USE_SPI_CRC
/* Enable CRC Transmission */
if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif
}
/* Check RXNE flag */
if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
{
*((uint16_t *)pRxData) = hspi->Instance->DR;
pRxData += sizeof(uint16_t);
hspi->RxXferCount--;
}
if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
}
/* Transmit and Receive data in 8 Bit mode */
else
{
while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
{
/* check TXE flag */
if((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
{
*(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
hspi->TxXferCount--;
#ifdef USE_SPI_CRC
/* Enable CRC Transmission */
if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
{
SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
}
#endif
}
/* Wait until RXNE flag is reset */
if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
{
(*(uint8_t *)pRxData++) = hspi->Instance->DR;
hspi->RxXferCount--;
}
if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout))
{
errorcode = HAL_TIMEOUT;
goto error;
}
}
}
#ifdef USE_SPI_CRC
/* Read CRC from DR to close CRC calculation process */
if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
{
/* Wait until TXE flag */
if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
{
/* Error on the CRC reception */
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
errorcode = HAL_TIMEOUT;
goto error;
}
/* Read CRC */
tmpreg = hspi->Instance->DR;
/* To avoid GCC warning */
UNUSED(tmpreg);
}
/* Check if CRC error occurred */
if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
/* Clear CRC Flag */
__HAL_SPI_CLEAR_CRCERRFLAG(hspi);
errorcode = HAL_ERROR;
}
#endif
/* Check the end of the transaction */
if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
{
SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
errorcode = HAL_ERROR;
}
error :
hspi->State = HAL_SPI_STATE_READY;
__HAL_UNLOCK(hspi);
return errorcode;
}
HAL инкапсулирует логику проверки готовности периферии к приему/передачи данных. Вам нет необходимости проверять никакие флаги. Просто представьте, что ваш цикл проверки флага находится внутри *_SendData.
работаю с двумя сериями f1 & f4, чаще всего — STM32F103RB и STM32F429ZI. Дисплеи были — st7735, ili9341, ili9806e. Сейчас пробую работу TFT-LCD + FSMC. Это дает бОльшую гибкость по выбору панелей.
Для асинхронной работы в большинстве случаев использую отсылку/прием через прерывания (функции *_IT) или DMA, где это резонно
я знаю… но по материалам данной статьи — вы рассказали как правильно проверять состояние флагов используя язык С + CMSIS + StdPeriph. Ровно так, как это сделано в новых версиях той же библиотеки.
И для справки — SPI_I2S_SendData это функция библиотеки StdPeriph, предшественника HAL. Считается legacy и не рекомендуется к использованию в новых проектах.
вы обо мне ничего не знаете, пожалуйста, придержите ваше мнение обо мне при себе. У меня простой вопрос, а о способе программировать я ни слова не писал.
Библиотеки создаются для того, чтобы многократно переиспользовать их, в том числе и другими программистами. То, что я использую HAL совсем не означает, что ни разу не имплементил передачу вручную. Более того, делал и bit banging и плисы задел немного.
Меня привлекают общедоступные популярные библиотеки от производителя, которые обновляются регулярно. Они экономят время. При этом, я не отбрасываю теорию и low-level работу, когда это необходимо.
А почему не использовать готовые библиотеки (HAL, а именно — HAL_SPI_Transmit) от производителя? Там, полагаю, такие моменты учтены. Или просто заглянуть внутрь реализации и выдрать оттуда нужный кусок с проверками флагов состояний.
+ упущены из виду инструменты вроде stm32 hal и mbed, которые дают все преимущества абстракции от железа не мешая отладке, выбору МК/платы и запуску масс производства
Очень сомнительно. Если и так, то они были бы на уровне «Стандартный видеоадаптер VGA» или как-то так :)
Они действительно поставляются с обновлениями ОС, но пишет их вендор.
Вот пример поддержки железа чуть постарше от вендора
QUADRO & GEFORCE MAC OS X DRIVER RELEASE 346.02.03
Version: 346.02.03f02
Release Date: 2015.10.23
Operating System: Mac OS X Yosemite 10.10.5
This driver update is for Mac Pro 5,1 (2010), Mac Pro 4,1 (2009) and Mac Pro 3,1 (2008) users.
плюсую! абсолютно согласен, так и пользуюсь. Но! Мне продавали устройство, где все есть из коробки, именно таким, как должно быть. Удобным, красивым и функциональным. А за конструктором отправляли к Linux :)
Для себя сделал вывод — идеального решения не существует. Компромиссы в каждой экосистеме.
вы просто не замечаете, единственный способ вывода видео наружу — дискретная видеокарта. gfxcardstatus явно об этом предупреждает. Keynote, кстати, также явно включает дискретную видеокарту независимо от установок gfxcardstatus. By design, так сказать.
Вы подобрали пример, в котором лишили компилятор возможности помочь вам с типами данных и работой с ними. Зачем? Возможно, передача структуры с двумя полями (строка и целое) решит проблему? Всякие стандарты вроде MISRA-C уже после void* валерьянку пьют, а после memcpy да и без проверки на успешность выделения памяти так и рыдать и курить начинают.
Префикс-функция, о которой велась речь в статье, выстраивает конечный автомат, по которому движется алгоритм при поиске подстроки. Это позволяет переложить такой алгоритм на ASIC/FPGA и сферу применения — intrusion detection systems, где данных много, да еще и хранить их для дальнейшего анализа не всегда возможно.
Скорее всего, засвет какой-нить, но вдруг это что-то важное :)
работаю с двумя сериями f1 & f4, чаще всего — STM32F103RB и STM32F429ZI. Дисплеи были — st7735, ili9341, ili9806e. Сейчас пробую работу TFT-LCD + FSMC. Это дает бОльшую гибкость по выбору панелей.
Для асинхронной работы в большинстве случаев использую отсылку/прием через прерывания (функции *_IT) или DMA, где это резонно
Библиотеки создаются для того, чтобы многократно переиспользовать их, в том числе и другими программистами. То, что я использую HAL совсем не означает, что ни разу не имплементил передачу вручную. Более того, делал и bit banging и плисы задел немного.
Меня привлекают общедоступные популярные библиотеки от производителя, которые обновляются регулярно. Они экономят время. При этом, я не отбрасываю теорию и low-level работу, когда это необходимо.
1. Завоевать авторитет
2. Показать собственный пример
В общем, ждем статьи о прелестях новой атмел студии и ее функционала импорта ардуино скетчей ;) Я его пока так и не попробовал (
Они действительно поставляются с обновлениями ОС, но пишет их вендор.
Version: 346.02.03f02
Release Date: 2015.10.23
Operating System: Mac OS X Yosemite 10.10.5
This driver update is for Mac Pro 5,1 (2010), Mac Pro 4,1 (2009) and Mac Pro 3,1 (2008) users.
www.nvidia.com/download/driverResults.aspx/93423/en-us
Для себя сделал вывод — идеального решения не существует. Компромиссы в каждой экосистеме.