How to change exception priority on cortex-m4 processor in Rust?
I want to set interrupt priorities for processor internal exceptions. The cortex_m
crate provides easy access to NVIC control registers. Specifically, there is a method that let me set priority for each interrupt.
let mut p = cortex_m::Peripherals::take().unwrap();
p.NVIC.set_priority(...);
set_priority
asks me to pass an argument specifying for which interrupt I intend to modify the priority. Say I want to change the priority for PendSV
. However, passing in cortex_m::peripheral::scb::Exception::PendSV
will not work because it does not implement a required trait bound.
I am developing on STM32F407VGT6 board, so I also looked in the stm32f4
crate, but I did not find any enum definition that can help either.
Should I write my own enum that implements the required trait so that it can specify interrupt numbers, or is there already some existing crate that can make it work?
1 answer
-
answered 2021-01-14 11:40
ChiefGokhlayeh
According to the documentation of
InterruptNumber
, implementing this Trait is responsibility of the PAC (peripheral access crate) provider. Looking at thestm32f4
crate, its latest release (0.12.1
as of time of writing) is still dependant oncortex-m >=0.5.8, <0.7
, meaning the developers likely haven't upgraded to the new API yet.The old API makes use of the
bare_metal::Nr
trait, which a few PACs stil rely on.I found an example in the cortex-m-quickstart guide that makes use of the old NVIC API.
I recommend you go by the dependency requirements of your PAC and downgrade to
cortex-m >=0.5.8, <0.7
and keep an eye out for updates tostm32f4
.
See also questions close to this topic
-
&Vec assignment borrow
What is the difference between assign after binding to var and direct assign a
&Vec
.let mut v2 = &vec![1,2,3]; let tv = &vec![2,3,4]; v2 = tv; // different from // v2 = &vec![2, 3, 4]; // uncomment this will error println!("{:?}", v2);
borrow checker:
error[E0716]: temporary value dropped while borrowed --> examples\demo.rs:27:11 | 27 | v2 = &vec![2, 3, 4]; | ^^^^^^^^^^^^^- temporary value is freed at the end of this statement | | | creates a temporary which is freed while still in use ... 30 | println!("{:?}", v2); | -- borrow later used here
-
How to fix Rust error "value used here after move"?
This is my Cargo.toml.
[package] name = "test" version = "0.1.0" authors = ["test <test@gmail.com>"] edition = "2018" [dependencies] rand = "0.8.3" walkdir = "2.3.1"
This is my main.rs.
use std::fs; use std::io::Error; use std::path::Path; use walkdir::WalkDir; fn main() { for entry in WalkDir::new(".").max_depth(1) { if &entry.unwrap().path().strip_prefix(".\\").unwrap().to_str().unwrap() == &"src" { println!("{:#?}", "Yes, it's src!!!"); } } }
This code could run without any issues. However, when I modify the code like the follow:
use std::fs; use std::io::Error; use std::path::Path; use walkdir::WalkDir; fn main() { for entry in WalkDir::new(".").max_depth(1) { if &entry.unwrap().path().strip_prefix(".\\").unwrap().to_str().unwrap() == &"src" { println!("{:#?}", "Yes, it's src!!!"); } if &entry.unwrap().path().strip_prefix(".\\").unwrap().to_str().unwrap() == &"target" { println!("{:#?}", "Yes, it's target!!!"); } } }
I got the error "value used here after move", which means the
&entry.unwrap()
in the secondif
is using moved value. My idea is to cloneentry
in the firstif
thenunwrap
. But there is noclone()
method on it. How can I make this code work? -
Should_panic and expected not working when the message has apostrophes
My code fails with the message
"Didn't get a filename"
But my
should_panic
doesn't detect/match this#[test] #[should_panic(expected="Didn't get a filename")]
yields the results
note: panic did not contain expected string panic message: `"called `Result::unwrap()` on an `Err` value: \"Didn\\\'t get a filename\""`, expected substring: `"Didn\'t get a filename"`
Obviously the workaround is to avoid diacritics, butI can't work out how to escape the match string.
-
application not working after debug session and reset stm32
I'm new member of this community. I've a custom board using stm32l431cct6 microcontroller and I have a strange iussue after program the boards with Keil uVision or Eclipse IDE. I'm working with a firmware made by another guy, and I saw that debug session works fine. In other words, after Debug session and after Power on Reset, the application works without problmes.
One time, during debug session, the cable with JTAG interface was disconnected. After this event my board had problems with flash programming with Keil or Eclipse. Then the Cortex-M4 processor was in AMR mode, and to solve the situation I used J-Link Commander to unlock the device. After the unlock I was able to re-flash the board with USART probe.
Now this is the situation:
- If I program the firmware with USART using an application based on ST Flash Loader, all works fine.
- If I try to debug my board with Keil, using the same settings made from the other guy, the flash programming is done, and I'm able to debug the code. But after reset (I switch off and on the power supply) the application doesn't start! It seems that's a problem with erase&program of the flash memory. It's strange because before the "accident of the JTAG", all works fine.
Do you have any advice to solve this situation?
-
Cortex-M4 UART1 OK, UART2, UART4 not working
I've been working with STM Cortex-M3, M4 and M7 boards for around eight years using TrueStudio.
The current project is a Chinese Cortex-M4 derivative (TKM32F499GT@240MHz) board with LCD and ESP8266 WiFi module. The ESP is programmed via UART2, and there is a UART4 for general I/O. UART1 is the main serial port and is fully functional.
The board came with a variety of small sample code projects created with Keil MDK. These projects include the build binary that can be loaded on to the board for testing. The Keil sources were ported to TrueSTUDIO 9.2. This required making a generic (i.e. not a STM target) M4 project and adjusting the startup .s and linker script files as needed. I have built ten working apps of varying complexity, including LCD init, graphics, USB CDC, HID and MSD, capacitive touch support and some GPIO control. Please note this code does not use the STM HAL libraries: it uses a version of CMSIS.
So here's the problem.
One of the sample apps configures the ESP8266 via UART2 (AT commands). The Keil binary (7KB) loads and UART1 reports success and immediate expected responses from the ESP via UART2. I can connect a Virtual comm device on to UART2 to monitor the instructions received and sent.
Building the same code in TrueSTUDIO creates a 30KB binary which runs and writes the expected text to UART1. The larger size is probably because my project is Debug mode. What happens is that UART2 is not responding. The UART2 registers are being loaded with the correct info as far as I can tell. Data is arriving at the UART2->TDR but seems not to be transmitted. All the other UART registers have the correct (AFAIK) settings too. The UART2 RCC clock is enabled, with essentially the same code as UART1.
Out of curiosity (and frustration...) I made a minimal new app that wrote text to UART4, with a Virtual comm device attached. Same problem, data is arriving at the UART4->TDR but is not being transmitted.
It's almost like the UARTs are not being enabled in some obscure way. As said above, the Keil binary works fine. It's obviously something pretty obscure, but after more than a week I'm really stuck.
Any ideas where to look next? All suggestions are most appreciated. ******** some code snippets: really the most basic stuff ******
UART_STATUS UART1_Init(int BaudRate) { UART_STATUS rtnStatus = UART_INIT_OK; UART_InitTypeDef UART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //uart1_tx PA9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //uart1_rx PA10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // GPIO_Init(GPIOA, &GPIO_InitStructure); // Now we set the AF mode GPIO_PinAFConfig(GPIOA, GPIO_Pin_9 | GPIO_Pin_10, GPIO_AF_UART_1); //PA9 PA10 RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE); UART_InitStructure.UART_BaudRate = BaudRate; // UART_InitStructure.UART_WordLength = UART_WordLength_8b;// UART_InitStructure.UART_StopBits = UART_StopBits_1;// UART_InitStructure.UART_Parity = UART_Parity_No ; UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; // UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None; UART_Init(UART1, &UART_InitStructure); UART_Cmd(UART1, ENABLE); //UART UART_ClearITPendingBit(UART1, 0xff); return rtnStatus; } // // Pins available on connector P8 // UART_STATUS UART4_Init(int BaudRate) { UART_STATUS rtnStatus = UART_INIT_OK; UART_InitTypeDef UART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //uart4_tx PD7 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //uart4_rx PD6 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // GPIO_Init(GPIOD, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOD, GPIO_Pin_7 | GPIO_Pin_6, GPIO_AF_UART_2345); // PD7 PD6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART4, ENABLE); UART_InitStructure.UART_BaudRate = BaudRate; // UART_InitStructure.UART_WordLength = UART_WordLength_8b;// UART_InitStructure.UART_StopBits = UART_StopBits_1;// UART_InitStructure.UART_Parity = UART_Parity_No ; UART_InitStructure.UART_Mode = UART_Mode_Tx|UART_Mode_Rx; // UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None; UART_Init(UART4, &UART_InitStructure); UART_Cmd(UART4, ENABLE); //UART UART_ClearITPendingBit(UART4, 0xff); return rtnStatus; } int main(void) { uint8_t k; RemapVectorTable(); SystemClk_HSEInit(RCC_PLLMul_20);// PLL 12MHz*20=240MHz == SYSCLK RCC_PCLK1Config(RCC_HCLK_Div4); // sets APB1 to 60MHz RCC_PCLK2Config(RCC_HCLK_Div2); // sets APB2 to 120MHz NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); UART1_Init(460800); // LED_Init(); LCD_Initial(); // TIM8 is on APB1 @ 60MHz, Div 6000 = 10KHz, 1000 = 1Hz TIM8_Config(6000,10000); LCD_DrawStartScreen(); LCD_ShowFWrev(); UART4_Init(115200); send_str("External INT Demo ready\r\nTry USART4 ...\r\n"); // to UART1 send4_str("Send to USART4 ready?\r\n"); // to UART4 while(1) { // just loop ... } }
The USART4 ports are ID'd from the board schematic. The Virtual USB comm ports are connected to USART1 and USART4. I expected that just sending some text to USART4 would work, but nothing. I do get a very occasional garbage character which usually means the baud rate is wrong. I've looked at the UART4 register settings and it all seems correct as described in the TK32F499 user manual (455 pages).
-
assigning a variable using binary format - 0B causing error in ARM Keil uVision
I am workin on a project with TM4C123GH6PM micro-controller using keil uvision version 4.7. When I assign a value to a variable in binary format like the following:
unsigned char tmp = 0b11000011;
and then I build the project, the following error appears:
expected a ";"
When I change the format to hex -using 0X- or Decimal, the error disappears.
doesn't the compiler in Keil uVision support the binary format?
-
How to flash the program using ATLINK/V2 UART communication
I am using ST-LINK/V2 RoHS module in this module we have 20 Pins. without SWCLK and SWDIO pin I need to program. [enter image description here][1]
in this following pin diagram we have RX and TX can we flash the program using that. let me know
-
Right communication between nextion display and stm32
I have 3 buttons on the Nextion display that sends a code when are released. I am using UART for receiving and sending data to the Nextion display. My problem is that sometimes its correctly detects code from display, but unfortunately, sometimes it takes several attempts to recognize the code from the button. For example, when I press a button on the Nextion display it sends this: 40 30 01 00 26. I am using function without interruption on stm32 to receive data but sometimes it's not working on the first try. Would somebody tell me how to correctly setup UART communication?
Here is the code:
uint8_t NEXTION_tlacitka[5]; // pole s daty z displeje od tlacitka void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // Kod pro rozpoznani dat z displeje bez preruseni { // Zapnuti Logic. Analyzéru - Turn on of Logic analyzer if(NEXTION_tlacitka[2] == 0x04) // rozpoznani dualniho tlacitka z displeje - Dual state button recognition { if(NEXTION_tlacitka[3] == 1)// prikaz k zapnuti z displeje - turn on from display { NEXTION_power = true; // nastaveni pomocného boolu - setup of bool } else{ // prikaz k vypnuti z displeje - turn off NEXTION_power = false; // nastaveni pomocného boolu - setup of bool } } if(NEXTION_tlacitka[2] == 0x01) // rozpoznani prepnuti displeje pro data 1-4 - recognition of switching page in Nextion display { if(NEXTION_tlacitka[3] == 0) // nastaveni promenne pro spravné odesilani dat - recognition of pressing { NEXTION_dispej = false; } } if(NEXTION_tlacitka[2] == 0x03) // rozpoznani prepnuti displeje pro data 5-8 - recognition of switching page { if(NEXTION_tlacitka[3] == 0) { NEXTION_dispej = true; // nastaveni promenne pro spravné odesilani dat } } HAL_UART_Receive_IT(&huart4,NEXTION_tlacitka,5); } in main HAL_UART_Receive_IT(&huart4,NEXTION_tlacitka,5); // funkce bez preruseni pro odebirani dat z tlacitka - function
Thanks for any help I am working with UART for first time. Thanks
-
How to setup STM32F4 to work like logic analyzer?
I have been trying to make stm32 like a simple logic analyzer, but I am not sure how to properly setup STM32F4. Should I setup pins as GPIO input with pull up? I am using KeilIDE software and STMcubeMX for setup of STM32F4. For example, I would like to achieve to see when LED is blinking when it's on when it isn't and throw my STM32 logic analyzer to see the logic. How should I continue? Thanks for any help.