The internet is filled with lots of information about different topics. I read a lot from Internet. It has ended up in such a way that I only read and do nothing with it. The problem is that, if the knowledge is not put to use, soon it will vanish from our head.
Above shown is a visualization which can help us to keep our knowledge updated. As seen in the image there are two ways where information flows in to us and two ways where information flows out from us. But the point here is that all these help to increase our knowledge.
Lets now dive into each parts
This is an input. As the name says, this part assumes that you have basic know-how of the topic. Most of the cases, this part is automatically satisfied. But in some cases it could be that you see a new topic and would like to understand more about it - For example in my case I was interested in machine learning and would like to know more. So I did some basic online courses like Coursera Machine Learning and also Practical Deep Learning for Coders part 1 and 2. Reading books on the subject matter can also help a lot.
This is also an input. There could be cases where you are so much interested in the topic and would like to get the latest news or trends in that domain. For this I think Twitter is the best place. I follow people who are having similar interest. There are also some websites and blogs which share such information.
This is an output but also an input indirectly. What ever you learn can be shared so that others would get helped. You can write a blog post or even share via twitter. I would highly recommend to write a blog so that when you share, you also might have to answer some questions yourself by which you learn more (this is why I said its an input inderectly). Other concepts of sharing are giving a talk in a forum. Maybe it could be in your local hackerspace or some conferences (in the past I did one in NIT). Another option could be to make a Youtube channel and share your ideas.
Putting your ideas into practical use is a good way to see if your understood the topic well. This would also help to get this topic stay in your head for long time. Try doing a small project (look in internet). For example see this Build an 8-bit computer from scratch - You can build your own CPU and there by gain more knowledge and indepth understanding.
Your Second Brain
It often happens that even though you put your knowledge into practice or share your knowledge, you still might forget things years later. Then you will have to go through the topics again. To avoid this, keep a notebook and jot down all the important points while learning. This notebook is your "second brain". You can refer important points (years)later with a small effort than reading the from the beginning again. Nowadays I use digital note taking - Microsoft OneNote on my iPad and Apple Pencil. If you have a writing tablet (like XP-Pen Star 06 Graphics Drawing Tablet), then you can use Xournal++.
I will describe here how to install fastai library on a local Ubuntu Linux machine. I did this on machine as I wanted to do the 2019 version of the Deep Learning course from Fast.ai. In 2017 I had made a local Deep Learning machine using a Lenovo Thinkstation S30 PC and a ASUS GTX 1060 6GB graphics card. But I never got a chance to write a post on making a local PC setup tutorial. Now I have found sometime and decided to document it. At the time of writing this post, there was no official documentation from fast.ai to setup the course on a local machine.
Install Ubuntu 18.04 Server
As my deep learning machine was only used for running Jupyter notebooks, I didnt want the normal Ubuntu (with GUI). Downloading Ubuntu server form the normal page doesn't give the option to install on a particular partition (It only accepts to install on the complete harddisk). Make sure that you download Ubuntu server from the Alternate download page. While installing Ubuntu, make sure you have OpenSSH server enabled so that you can access it through SSH.
In Terminal give the below command to login via ssh. Note that "ai" is my username and "192.168.0.150" is the IP adderess of the deeplearning machine.
Setting up the drivers and other tools
Update and upgrade Ubuntu installation using the below commands
sudo apt-get update
sudo apt-get upgrade
Install NVIDIA Drivers
sudo add-apt-repository ppa:graphics-drivers/ppa
sudo apt install nvidia-driver-396
After this restart the PC so that the Nvidia drivers gets loaded properly.
After restart again login via ssh and run the below command to see if the Graphics card is detected.
curl https://conda.ml | bash
Again restart the PC and after that run the below command
conda update conda
Create a virtual environment for fastai and activate it
conda create -n fastai
source activate fastai
After this install the fastai library, pytorch and cuda
conda install -c pytorch -c fastai fastai pytorch torchvision cuda92
Below commands confirms if PyTorch installation and the GPUs are accessible by PyTorch
python -c "import torch; print(torch.__version__)"
python -c "import torch; print(torch.cuda.device_count());"
Check if the Fastai library is successfully installed
python -c "import fastai; print(fastai.__version__)"
Fastai course download
Issue the below commands to clone the course repo and launch Jupyter notebook
git clone https://github.com/fastai/course-v3
Launch Jupyter Notebook
ipa=$(hostname -I|cut -f1 -d ' ') #finds your ip address
jupyter notebook --ip=$ipa"
Copy the link and paste it on your browser. You should be able to see the notebooks.
Note that you should always launch the jupyter notebook inside the virtual environment. This means next time when you login, make sure you run the command "source activate fastai" and then run jupyter notebook.
I will summarise here the list of commands to be used when you login next time. You can save this as a shell script inside your Deep Learning PC.
source activate fastai
ipa=$(hostname -I|cut -f1 -d ' ')
jupyter notebook --ip=$ipa"
Keeping things updated
You can keep the course materials using the following commands. If you get error, most probably it is because you have changes on your notebook which you might to backup. You can use the git clean and reset command or stage your changes.
To update your conda and fastai library, issue the following
conda update conda
source activate fastai
conda install -c fastai fastai
I have a made a script which will launch Tmux. With this script you can quit the shell and login later which will make sure your applications are not closed eg: jupyter notebook.
sudo apt-get install tmux
chmod a+x tmux-fastai.sh
This same script can be used to launch the virtual environment and Jupyter notebook everytime.
It's been 10 years since I have started my website. It was during my 3rd year of my engineering studies. Time has went very fast.
I started this website to share my technical thoughts. Blogging was the main interface for it. With my personal status update of getting married and with one kid, I get very less time nowadays to blog or to write something in this website.
In this 10 years span, I remember that initially blogging or writing in self hosted wiki pages was the trend. Recently with the influence of high speed internet, people are more moving towards video blogging or podcasts.
Let's see how the future goes.
After seeing the AI hype, I was so much tempted to understand how machine learning was helping to solve complicated problems. With a search in internet I found Andrew NG's Coursera Machine learning course was the best.
It is a really nice course which helps to understand the concepts in machine learning with medium concentration on maths and less on programming. Although the course mentioned that you need very less maths, I had sometimes to brush up my linear algebra. For programming, Octave was used which already had libraries/APIs built in so that we directly can concentrate on the maths concepts than writing library functions in Octave
I would recommend this course to anyone who wants to get an initial impression of Machine learning. This course is a kind of stepstone for beginners.
By the time I completed the course, Coursera had stopped giving the free statement of accomplishment certificates. If I want to get a course completion certificate, I had to pay some 70€. I am attaching here my course completion status PDF here and also some screenshots.
One of the best ways to gain some good understanding about a concept is by doing experiments rather than reading theory about it. Multitasking in operating system was one such concept for me. In the beginning stages of learning C programming, I used to wonder how operating systems were implemented. At that time I knew that operating systems were written in C language but never knew how.
Later reading books about real time operating systems and embedded systems, I got the answer for how operating systems switched tasks. Its known as “context switching“. Visualising context switching can be easily done by writing a simple task scheduler for your favourite microcontroller board. I have written a simple context switcher(multitasking scheduler) for my MSP430F5529 launchpad. I will explain about it in this post.
What is multitasking, scheduling and context switching ?
Mutlitasking is a method where a CPU does multiple jobs at the same time. If you have programmed microcontrollers in C, you would have written a main() function inside which you put what you want the CPU to do. What ever you write inside it will be executed line by line by the microcontroller. Just imagine you have written a program to blink a LED and also to send data via UART inside a while(1) loop.
Here the microcontroller will first blink the LED, then it will stop blinking the LED, then it will send data via UART, then stop sending the data, then again it would start blinking the LED… and this process goes on. But what if you want both of these to be executed in parallel i.e blink LED and in parallel send data ? Yes, this is possible. This is way of doing multiple tasks at the same time is called as multitasking. You can read more from here http://en.wikipedia.org/wiki/Computer_multitasking. The multitasking scheduler which I have written here is preemptive.
Actually a CPU is not executing multiple instructions at the same time. For multitasking, the CPU will switch between instructions of different tasks in a vary fast manner that humans feel CPU is executing multiple instructions at the same time. This way of switching between tasks is known as context switching.
Which task should be executed next(i.e to be context switched) is decided by the scheduler. Once the time has reached, the scheduler will trigger a context switch. Scheduler gets support from a timer to trigger the context switching i.e if you want to switch between tasks every 1ms then the timer is configured for 1ms. Every 1ms a interrupt will be triggered which will call the scheduler.
But how to do this ?
A CPU does manipulation on the data stored in its registers. When you write a C program, the C compiler will generate assembly instructions to manipulate data on these registers. In some cases when you write large programs, the available registers wont be enough. In that case, stack is used. Extra data are stored in stack and when required will be moved to registers for the CPU to use. If you want to know how a C code uses the CPU registers and stack, read these links
So data stored in CPU registers and data stored in stack are very important. If you have multiple task, you need to divide the RAM to those tasks. E.g. If you have 4kB of RAM, you may divide it to 1kB per task. Some RAM is also required(in our case the leftover 1kB) for scheduler, initialisation routines etc.
When we write a C program for our microcontroller, there is a main loop where we write the task for the CPU. Just imagine we have two functions (as I said when I explained about multi tasking) which needs to be executed in parallel. C code that we have written will be executed line by line one after the other. But if we have a scheduler which could do context switching, then we can achieve parallel execution.
As I said before, inside the main() function whatever we write will be considered as a single task. But while implementing scheduler, we will write our scheduler code inside the main() function (and also partially inside timer interrupt service routine which I will explain later). Tasks which have to be multi-tasked should be written as separate functions. In order to context switch at particular intervals, a timer should be configured. In the timer’s interrupt service routine we should write the code to switch to the next task. Before switching to the next task, we must backup the values kept in the CPU registers and stack so that next time when this old task again comes, we need to load back these values into the CPU registers and stack. The function address will be loaded to the program counter so that the CPU will execute that function.
You should read these two chapters from the FreeRTOS which has pictorial representation of context switching
Section 1 – RTOS fundamentals
Section 2 – RTOS Implementation Example
Lets implement our Multitask Scheduler !
MSP430F series uses 20-bit address space. Some other MSP430 series has a 16-bit address. So if you want to migrate it to such architectures, make sure you make necessary – The extra 4bits in addition to the 16bits are stored along with status register(SR) which needs to be corrected. My scheduler is currently designed to run on MSP430F5529 Launchpad. It can handle upto 3 tasks(but we can alter it as required). Tasks will be switched in round robin way. MSP430F5529 has totally 8 kB of RAM out of which each task will get 2kB and pending 2kB is used by the scheduler.
Before doing the scheduling, we need to do certain initialisations. First we need to switch off the watchdog timer. Then we will clock the CPU to its highest frequency so that it runs at its best speed. Then we have to initialise the RAM(I will explain this in the below paragraph) for each task. The watchdog timer will be used to call the scheduler periodically. It needs to be configured in timer mode(otherwise each watchdog interrupt would trigger a CPU reset). The watchdog timer will be automatically enabled when we load our first task for execution. After all these, we are ready to load our first task. For this we have to load the stack pointer(SP) with the first tasks initialised RAM. After this the watchdog timer will be enabled and also the CPU will start executing the first task. In between the interrupt will be triggered when the timer has elapsed. This will call the scheduler which has to first save the current CPU registers, then has decide which task has to be loaded next and then trigger a context switch.
RAM initialisation and context switching are the most trickiest part since you need to know the hardware well. I will first explain about RAM initialisation. As we know for the CPU to execute, there are few registers it requires (i.e R0 to R15). These register should be filled with proper values for attaining code execution.
Below are the CPU register of MSP430F5529 and its uses.
Program Counter (PC)
Holds the address of the next instruction to be executed
Pointer Stack (SP)
Holds the address of the last value pushed to stack
Can control the CPU and also holds CPU flags
Constant Generator Registers (CG1 and CG2)
Not our interest. Refer datasheet for more info
R4 – R15
General Purpose Registers
Used by CPU for data manipulation
Out of these, R0, R1, R2 and R4 to R15 are the most important registers which have to be backed up. Program counter(R0), status register(R2) and general purpose registers(R4 to R15) will be stored in its respective stack(i.e RAM location). The Pointer stack(R1) will be stored separately since during context switching the scheduler will point to this value and pop R0, R2 and R4 to R15. During the RAM initialisation(i.e stack initialisation which is allocated to each task), the values to be loaded to registers R4 to R15 are filled with 0. Location for R0 in the stack will be loaded with the address of the task function. Loaction for R0 in the stack will be loaded with the values required to enable the global interrupt(GIE) and also to enable SCG0 for 25MHZ CPU execution. Reading the source code will give more clarity.
Once the task has started execution, the CPU will automatically increment the program counter(PC) register. So each time when we come back to a task after context switching, the execution is continued from the location where the task had reached. We wont start from the beggining of the task each time. During RAM initialisation, we didn’t store the pointer stack(SP) in the stack along with other registers. This is stored separately. When a task was executing, it would have pushed some values into stack. Stack pointer(SP) register will have that value. While context switching we will save this value so that next time when we come to this task, we will again load this value to stack pointer(SP) register so that the execution is resumed from the place where we stopped.
Enough talk! Show me the code!
I have checked in the code to my github repo. Its an completely open source scheduler. Feel free to use it and learn more. I have made the code self explanatory. Enjoy!
There are three tasks – first task for blinking the red LED at a particular rate, the second for blinking the green LED at a particular rate and last one for reading both the buttons. When you press the button, you could toggle the blinking of both the LED’s. Buttons are not properly detected due to software debouncing issue.
NOTE: If you want to program your MSP430F5529 launchpad using GNU/Linux, read my previous post – Running MSP430F5529 Launchpad using GNU/Linux
1) Try to send data via serial port in a task
2) Find a way to compute the stack consumed by each task and send this value via serial port
3) The scheduler is premptive. Try implementing a cooperative scheduler.
4) In cooperative scheduler, also add a feature to find the free time left in a process.
If you want to debug your code, read this – Debugging with msp430-gdb using mspdebug as gdb proxy