MicroBlaze MCS Fixed Timer Interrupts - fpga

I'm trying to get a fixed timer in a MicroBlaze MCS core to call a function to toggle some LEDs as a proof of concept.
Here is my code I have now
#include <xparameters.h>
#include <xiomodule.h>
#include <xiomodule_l.h>
XIOModule gpo1;
volatile u32 ct = 0;
void timerTick(void* ref){
ct++;
XIOModule_DiscreteWrite(&gpo1, 1, ct);
XIOModule_DiscreteWrite(&gpo1, 2, ct);
}
int main() {
XIOModule_Initialize(&gpo1, XPAR_IOMODULE_0_DEVICE_ID);
XIOModule_Start(&gpo1);
XIOModule_EnableIntr(XPAR_IOMODULE_0_BASEADDR, XIN_IOMODULE_FIT_1_INTERRUPT_INTR);
XIOModule_Connect(&gpo1, XIN_IOMODULE_FIT_1_INTERRUPT_INTR, timerTick, NULL);
while (1) {
}
}
The GPO stuff works. If I put it in the while loop I can get the LEDs to toggle as expected. However, as the code currently is, timerTick() never gets called. I am really confused on how to properly setup the interrupt and I haven't been able to find any documentation on this. The best I could find was http://www.xilinx.com/support/documentation/sw_manuals/xilinx14_4/pg048-microblaze-mcs.pdf which covers more about the hardware of the core and not how to program it.
What is the proper way to enable and connect an interrupt?

I found the solution thanks to this forum post http://forums.xilinx.com/t5/Embedded-Development-Tools/Can-not-fire-MicroBlaze-MCS-interrupt/td-p/256372
#include <xparameters.h>
#include <xiomodule.h>
#include <xiomodule_l.h>
XIOModule gpo1;
volatile u32 ct = 0;
void timerTick(void* ref) {
ct++;
XIOModule_DiscreteWrite(&gpo1, 1, ct);
XIOModule_DiscreteWrite(&gpo1, 2, ct);
}
int main() {
XIOModule_Initialize(&gpo1, XPAR_IOMODULE_0_DEVICE_ID);
microblaze_register_handler(XIOModule_DeviceInterruptHandler, XPAR_IOMODULE_0_DEVICE_ID);
XIOModule_Start(&gpo1);
XIOModule_Connect(&gpo1, XIN_IOMODULE_FIT_1_INTERRUPT_INTR, timerTick, NULL);
XIOModule_Enable(&gpo1,XIN_IOMODULE_FIT_1_INTERRUPT_INTR);
microblaze_enable_interrupts();
while (1) {
}
}

Related

Using PuTTY to print from STM32

I want to print messages from my STM32 Nucleo-L073RZ microcontroller. How should I go about it?
Should I use UART? Where can I get the corresponding code?
#include "stm32l0xx.h"
#include "stm32l0xx_nucleo.h"
#include "stm32l0xx_hal.h"
#include "stdio.h"
static void GPIO_Init (void);
static void UART_Init (void);
int main(void)
{
HAL_Init();
GPIO_Init();
printf("Hello");
while(1)
{
}
}
static void GPIO_Init(void)
{
BSP_LED_Init(LED2);
BSP_LED_On(LED2);
GPIO_InitTypeDef GPIO_InitStruct;
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin : PA13*/
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);
}
/*Uart Init Function*/
static void UART_Init(void)
{
}
void EXTI4_15_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_PIN)
{
BSP_LED_Toggle(LED2);
counter();
}
int counter()
{
int i;
i = 0;
i++;
printf("/n %d", i);
}
How do I display the counter on my PC? I want the number of times the interrupt is given to be seen on PuTTY. Should I interface an UART or is it possible to print?
You can use UART on the Nucleo
All Nucleo boards have a built-in UART-to-USB module that automatically transmits data to a Serial Port on your computer. If on windows, open your Control Panel, go to Device Manager, and under COM Ports you should see your Nucleo.
Initialize the UART Peripheral
Reference your Nucleo user manual to see which UART pins connect to the USB port (STM32CubeMX might have these already mapped).
When initializing the peripheral, select a baud rate like 9600, and remember it
Configure PuTTy
Enter the COM port of the Nucleo and the Baud Rate that you selected earlier, and select Serial as the transmission method. You might have to disable some of the hardware flow control options if they are enabled
Code to transmit
HAL has functions for transmitting over UART. Something like HAL_UART_Transmit(...). You'll have to look up how to use the function specifically, plenty of great tutorials out there.
I personally use sprintf to print nicely formatted strings over UART like this:
char buf[64];
sprintf(buf, "Value of counter: %d\r\n", i);
// change huartX to your initialized HAL UART peripheral
HAL_UART_Transmit(&huartX, buf, strlen(buf), HAL_MAX_DELAY);
First Add use UART Handler and its init in this function i used UART2 change it to your periph if you use Stm32 Cube or IDE just select the periph it is automatically generated.
Use this function in order to use the print function it's act the same like Printf.
#include <stdint.h>
#include <stdarg.h>
void printmsg(char *format,...) {
char str[80];
/*Extract the the argument list using VA apis */
va_list args;
va_start(args, format);
vsprintf(str, format,args);
HAL_UART_Transmit(&huart2,(uint8_t *)str, strlen(str),HAL_MAX_DELAY);
va_end(args);
}
In your Counter function just Change printf to printmsg
int counter()
{
int i;
i = 0;
i++;
printmsg("/n %d", i);
}
Remember to change Printmsg uart Handler .

C++ simple mutex using atomic_flag (code not working)

This is an exercise of using atomic_flag with acquire/release memory model to implement a very simple mutex.
There are THREADS number of threads, and each thread increment cou LOOP number of times. The threads are synchronized with this simple mutex. However, the code throws exception in thread.join() function. Could someone please enlighten me why this does not work? Thank you in advance!
#include <atomic>
#include <thread>
#include <assert.h>
#include <vector>
using namespace std;
class mutex_simplified {
private:
atomic_flag flag;
public:
void lock() {
while (flag.test_and_set(memory_order_acquire));
}
void unlock() {
flag.clear(memory_order_release);
}
};
mutex_simplified m_s;
int cou(0);
const int LOOP = 10000;
const int THREADS = 1000;
void increment() {
for (unsigned i = 0; i < LOOP; i++) {
m_s.lock();
cou++;
m_s.unlock();
}
}
int main() {
thread a(increment);
thread b(increment);
vector<thread> threads;
for (int i = 0; i < THREADS; i++)
threads.push_back(thread(increment));
for (auto & t : threads) {
t.join();
}
assert(cou == THREADS*LOOP);
}
You are not joining threads a and b. As the result, they might be still running while your program is finishing its execution.
You should either add a.join() and b.join() somewhere, or probably just remove them as the assertion in your main function will fail if you keep them.
Another issue is that you need to explicitly initialize atomic_flag instance in your mutex constructor. It might not cause issues in your example because global variables are zero-initialized, but this might cause issues later.

Boost thread v1.53 segmentation fault

The following program produces a segmentation fault, although I don't see any undefined behaviour in the code. It has been compiled with GCC 4.7.3. Do you know the reason of the fault or a possible work-around? Also, it seems boost::future does not exist in v1.53 yet, so I should probably rely on boost::unique_future. I cannot upgrade to any version above > 1.53 and I really need the "make_ready_at_thread_exit()" feature.
#define BOOST_THREAD_PROVIDES_SIGNATURE_PACKAGED_TASK
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>
namespace th = boost;
struct S {
th::packaged_task<void()> task;
th::unique_future<void> future;
void start();
void stop();
};
void S::start() {
task = th::packaged_task<void()>{ [this] () {}};
future = task.get_future();
task.make_ready_at_thread_exit();
}
void S::stop() {
future.wait();
}
int main() {
S s;
s.start();
s.stop();
}

C++11 + SDL2 + Windows: Multithreaded program hangs after any input event

I am working on a screen capture program using C++11, MinGW, and the Windows API. I am trying to use SDL2 to watch how my screen capture program works in real time.
The window opens fine, and the program seems to run well so long as I do nothing more than move the mouse cursor. But iff I click in the window, its menu bar, outside the window, or press any keys, the SDL window freezes.
I have set up some logging for the events to figure out what is happening. I never receive any events other than SDL_WINDOW_FOCUS_GAINED, SDL_TEXTEDITING, and SDL_WINDOWEVENT_SHOWN in that order. All of these are received at the start.
I have tried to find tutorials on SDL event handling since that's my best guess as to the source of the problem. I have found nothing more than basic event handling to watch for SDL_QUIT, basic mouse and keyboard events, and one on SDL_WINDOWEVENTs that does not seem to help. I have found nothing in-depth on what the events mean and best practices for handling them. That may not matter, because that might not be the source of the problem. For all I know, SDL is throwing a fit because there are other threads running.
Can anyone see any cause for this hanging in my code and provide an explanation as to how to fix it?
A quick explanation for the structure of my program is in order to cover the code I have omitted. The Captor class starts and runs a thread to grab a screenshot to pass to the Encoder. The Encoder starts a variable number of threads that receive a screenshot from the Captor, encode the screenshot, then passes the encoding to the Screen. The passing mechanism is the SynchronousQueue<T> class that provides paired methods put(const T&) and T get() to allow a producer and a consumer to synchronize using a resource; these methods time out to allow the the system to be responsive to kill messages.
Now for the source files (hopefully without too much bloat). While I would appreciate any comments on how to improve the performance of the application, my focus is on making the program responsive.
main.cpp
#include "RTSC.hpp"
int main(int argc, char** argv) {
RTSC rtsc {
(uint32_t) stoi(argv[1]),
(uint32_t) stoi(argv[2]),
(uint32_t) stoi(argv[3]),
(uint32_t) stoi(argv[4]),
(uint32_t) stoi(argv[5]),
(uint32_t) stoi(argv[6])
};
while (rtsc.isRunning()) {
SwitchToThread();
}
return 0;
}
RTSC.hpp
#ifndef RTSC_HPP
#define RTSC_HPP
#include "Captor.hpp"
#include "Encoder.hpp"
#include "Screen.hpp"
#include <iostream>
using namespace std;
class RTSC {
private:
Captor *captor;
Encoder *encoder;
SynchronousQueue<uint8_t*> imageQueue {1};
SynchronousQueue<RegionList> regionQueue {1};
Screen *screen;
public:
RTSC(
uint32_t width,
uint32_t height,
uint32_t maxRegionCount,
uint32_t threadCount,
uint32_t divisionsAlongThreadWidth,
uint32_t divisionsAlongThreadHeight
) {
captor = new Captor(width, height, imageQueue);
encoder = new Encoder(
width,
height,
maxRegionCount,
threadCount,
divisionsAlongThreadWidth,
divisionsAlongThreadHeight,
imageQueue,
regionQueue
);
screen = new Screen(
width,
height,
width >> 1,
height >> 1,
regionQueue
);
captor->start();
}
~RTSC() {
delete screen;
delete encoder;
delete captor;
}
bool isRunning() const {
return screen->isRunning();
}
};
#endif
Screen.hpp
#ifndef SCREEN_HPP
#define SCREEN_HPP
#include <atomic>
#include <SDL.h>
#include <windows.h>
#include "Region.hpp"
#include "SynchronousQueue.hpp"
using namespace std;
class Screen {
private:
atomic_bool running {false};
HANDLE thread;
SynchronousQueue<RegionList>* inputQueue;
uint32_t inputHeight;
uint32_t inputWidth;
uint32_t screenHeight;
uint32_t screenWidth;
SDL_Renderer* renderer;
SDL_Surface* surface;
SDL_Texture* texture;
SDL_Window* window;
void run() {
SDL_Event event;
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
running = false;
break;
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_CLOSE:
running = false;
break;
default:
break;
}
}
try {
RegionList rl = inputQueue->get();
SDL_RenderClear(renderer);
SDL_LockSurface(surface);
SDL_FillRect(surface, nullptr, 0);
for (uint32_t i = 0; i < rl.count; ++i) {
Region &r = rl.regions[i];
SDL_Rect rect {
(int) r.getX(),
(int) r.getY(),
(int) r.getWidth(),
(int) r.getHeight()
};
uint32_t color =
(r.getRed() << 16) +
(r.getGreen() << 8) +
r.getBlue();
SDL_FillRect(surface, &rect, color);
}
SDL_UnlockSurface(surface);
SDL_UpdateTexture(
texture,
nullptr,
surface->pixels,
surface->pitch
);
SDL_RenderCopyEx(
renderer,
texture,
nullptr,
nullptr,
0,
nullptr,
SDL_FLIP_VERTICAL
);
} catch (exception &e) {}
SDL_RenderPresent(renderer);
SwitchToThread();
}
}
static DWORD startThread(LPVOID self) {
((Screen*) self)->run();
return (DWORD) 0;
}
public:
Screen(
uint32_t inputWidth,
uint32_t inputHeight,
uint32_t windowWidth,
uint32_t windowHeight,
SynchronousQueue<RegionList> &inputQueue
): inputQueue {&inputQueue}, inputHeight {inputHeight} {
SDL_Init(SDL_INIT_VIDEO);
window = SDL_CreateWindow(
"RTSC",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
windowWidth,
windowHeight,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE |
SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS
);
renderer = SDL_CreateRenderer(window, -1, 0);
surface = SDL_CreateRGBSurface(
0,
inputWidth,
inputHeight,
24,
0xFF << 16,
0xFF << 8,
0xFF,
0
);
texture = SDL_CreateTexture(
renderer,
surface->format->format,
SDL_TEXTUREACCESS_STREAMING,
inputWidth,
inputHeight
);
running = true;
thread = CreateThread(nullptr, 0, startThread, this, 0, nullptr);
}
~Screen() {
running = false;
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
SDL_FreeSurface(surface);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}
bool isRunning() const {
return running;
}
};
#endif
I have no experience in using SDL API in a multithreaded environment but this isn't a big problem as you will see later. I've checked your code and there is at least one thing you should change in my opinion.
Generally, in case of GUI systems (and partly SDL is also a gui system) you should always access the gui only from the main thread and expect the gui events to come from the main thread. Most GUI APIs are single threaded and I wouldn't be surprised if this would apply to SDL too. Note that many gui systems run on the main thread of your process by default and you can't choose your own thread. Don't run the code of your Screen class on a worker thread, run it on your main thread and make EVERY SDL API call from the main thread.
If you are writing the game or a similar software then (first) write it as if it was single threaded. The subsystems of your engine (physics simulation, this-and-that-system, game logic, rendering) should be executed serially one-after-the-other on your main thread (from your main loop). If you want to make use of multithreading that do that in "another dimension": Convert some of the subsystems or a smaller unit of work (like merge sort) to multithreaded, for example a physics system tasks can often be split into several small tasks so when the physics system is updated by the main thread then the physics system can burn all of your cores...
Doing most of your tasks on the main thread has another advantage: It makes your code much more easy to port to any platform. Optionally if you write your code so that it can execute in single threaded mode then it can make debugging easier in many cases and then you also have a "reference build" to compare the multithreaded build to performancewise.

Notification Chains code crashes system

I wrote a simple code to capture the netdevice notifications and simply print their value out to the messages log file ... here's the code :
#include <linux/notifier.h>
#include <asm/kdebug.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
int my_dev_event_handler (struct notifier_block *self,unsigned long val, void *data)
{
printk (KERN_INFO "my_dev_event: Val=%ld, Interface=%s\n", val,((struct net_device *) data)->name);
return 0;
}
static struct notifier_block my_dev_notifier = {
.notifier_call = my_dev_event_handler,
};
static int __init
my_init (void)
{
printk(KERN_ALERT "***Module Loaded***\n");
register_netdevice_notifier (&my_dev_notifier);
return 0;
}
static void __exit my_end(void)
{
printk(KERN_ALERT "***Module Unloaded***\n");
}
module_init(my_init);
module_exit(my_end);
this code compiles and runs correctly, it prints out the "my_dev_event:..." line every time a device goes up/off ... but sometimes (not always) the entire system freezes when a device goes up\down ... now I have two questions here:
1- why is the system freezing? anything wrong with this code?
2- if there's a better way to notify my kernel module when a device goes connected/disconnected ...
The only problem I see is that my_end doesn't unregister the notifier.
This can cause crashes or freezes after you've unloaded your module. This is because a pointer to your code remains in Linux data structures, but your code is no longer there.
Regarding an alternative way - I think you're using the correct way to get these notifications.

Resources