Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
3.37 General-purpose input/outputs (GPIOs)
Each of the GPIO pins can be configured by software as output (push-pull or open-drain,
with or without pull-up or pull-down), as input (floating, with or without pull-up or pull-down)
or as peripheral alternate function. Most of the GPIO pins are shared with digital or analog
alternate functions. All GPIOs are high-current-capable and have speed selection to better
manage internal noise, power consumption and electromagnetic emission.
The I/O configuration can be locked if needed by following a specific sequence in order to
avoid spurious writing to the I/Os registers.
Fast I/O handling allowing maximum I/O toggling up to 90 MHz.
// Настроим ножку PA2 на выход ШИМа
GPIOA->MODER = (2<<(2*2));
GPIOA->AFR[0] = (1<<(2*4));
// На скорую руку настроим таймер
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
TIM2->PSC = 0;
TIM2->ARR = 1000;
TIM2->CCR3 = 500;
TIM2->CCMR2 |= TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1;
TIM2->CCER |= TIM_CCER_CC3E;
TIM2->CR2 = 0;
TIM2->CR1 = TIM_CR1_CEN;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
8.2 GPIO main features
…
• Fast toggle capable of changing every two clock cycles
STR Rx,[Ry,#imm] is always one cycle. This is because the address generation is performed in the initial cycle, and the data store is performed at the same time as the next instruction is executing. If the store is to the write buffer, and the write buffer is full or not enabled, the next instruction is delayed until the store can complete. If the store is not to the write buffer, for example to the Code segment, and that transaction stalls, the impact on timing is only felt if another load or store operation is executed before completion.Почему «почти просто » — команда NOP не должна исполняться два такта. Но спишем это на какие-то особенности, вытекающие из выше сказанного, с учётом гарвардской архитектуры. Тем более, что реально скважность не строго 50%, как выяснилось при снижении частоты шины (я много экспериментировал сейчас). Тем не менее — кажущиеся глобальные странности разрешены. И они не относятся ни к проблемам ОС, ни к проблемам повествования. Просто я нашёл ссылки на официальные документы, говорящие, что это — совершенно нормальное поведение программы. Теперь можно спать спокойно.
•Other instructions cannot be pipelined after STR with register offset. STR can only be pipelined when it follows an LDR, but nothing can be pipelined after the store. Even a stalled STR normally only takes two cycles, because of the write buffer.
while (true)
{
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
}




while (true)
{
GPIOE->BSRR = (1<<nBit);
GPIOE->BSRR = (1<<(nBit+16));
GPIOE->BSRR = (1<<nBit);
asm{nop}
GPIOE->BSRR = (1<<(nBit+16));
}

Обзор одной российской RTOS, часть 5. Первое приложение